看楼主写的好像还有其他错误 所以自己也写了一下  如有不足请指出哈! 
楼主的票数变量声明有问题, 应该使用静态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();
 
 -                                                 }
 
 -                                         }
 
  复制代码 
 
 
 
 
 |