看楼主写的好像还有其他错误 所以自己也写了一下 如有不足请指出哈!
楼主的票数变量声明有问题, 应该使用静态static
同步锁对象使用错误,使用this每次锁对象都会变,this不唯一,class是唯一的
不应该使用sleep sleep是进入睡眠 不释放锁对象,应使用wait wait是进入等待状态,需要主动唤醒 进入等待时 释放锁对象
- public class Test {
- public static void main(String[] args) {
- Thread t1 = new Thread(new Tickets());
- Thread t2 = new Thread(new Tickets());
- Thread t3 = new Thread(new Tickets());
- Thread t4 = new Thread(new Tickets());
- t1.setName("窗口1");
- t2.setName("窗口2");
- t3.setName("窗口3");
- t4.setName("窗口4");
- t1.start();
- t2.start();
- t3.start();
- t4.start();
- }
- }
- class Tickets implements Runnable {
- //将票数定义为静态变量 所有此对象共享,不会出现每new一次都是100
- private static int ticket = 100;
- @Override
- public void run() {
- while (true) {
- //同步 因为是多线程锁对象 不能使用this 使用this为谁调用我 我就是谁,显然多个线程每次锁对象都不同起不到效果
- //在这里需要使用字节码文件当做 锁对象,因为字节码文件是不会因对象改变而被改变的 无论多少线程 字节码文件都唯一
- synchronized (Tickets.class) {
- //票数小于0跳出循环
- if (ticket > 0) {
- //票数为90 因为ticket从100开始自减 90正好是第10张
- //票数为90 窗口不为3 线程进入等待 交出控制权 释放锁对象
- if (ticket == 90 && !"窗口3".equals(Thread.currentThread().getName())) {
- try {
- System.out.println(Thread.currentThread().getName()+"等待");
- //线程进入等待
- Tickets.class.wait();
- //恢复线程恢复后进入到循环尾部从新开始,防止继续进行操作
- continue;
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
复制代码
|