线程thread1获得对象锁遇后到wait方法时,该线程抛出锁;这之后是必须要等要notifyAll方法才能被唤醒吗?还是说该线程抛出锁后,会再一次继续同其他线程抢锁?请给我解释一下这方面的问题!

解决方案 »

  1.   


    //共享数据类
    class Producer{
    String name;
    int ticket=0;
    int i=0;
    //产票方法
    public synchronized void putTicket() throws InterruptedException{
    if(ticket<=0){
    ticket++;
    System.out.println("开始生产第"+ticket+"张票");
    }else{

    System.out.println("票有剩余,停止产票");
    notifyAll();
    wait();
    }
    }

    //买票方法
    public synchronized void getTicket() throws InterruptedException{
    if(ticket<=0){
    System.out.println(name+"停止售票");
    notifyAll();
    wait();
    }else{
    ticket--;
    i++;
    System.out.println(name+"出售第"+i+"张票");

    }
    }

    }
    //产票类
    class Department extends Thread{
    Producer p;
    public Department(Producer p){
    this.p=p;
    }

    public void run(){
    while(true){
    try {
    Thread.sleep((int)(Math.random()*30*100));
    } catch (InterruptedException e1) {
    e1.printStackTrace();
    }
    try {
    p.putTicket();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }

    }
    //买票类
    class Seller extends Thread{

    Producer p;
    public Seller(Producer p,String name){
    super(name);
    this.p=p;

    }

    public void run(){
    p.name=getName();
    while(true){
    try {
    Thread.sleep((int)(Math.random()*30*100));
    } catch (InterruptedException e1) {
    e1.printStackTrace();
    }
    try {
    p.getTicket();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }

    }
    //测试类
    public class TicketTest {

    public static void main(String args[]){
    Producer p=new Producer();
    Department d=new Department(p);
    Seller s1=new Seller(p,"窗口A"); 
    Seller s2=new Seller(p,"窗口B");
    Seller s3=new Seller(p,"窗口C");
    Seller s4=new Seller(p,"窗口D");
    d.start();
    s1.start();
    s2.start();
    s3.start();
    s4.start();
    }}
    为什么这段代码中,当一个线程进入同步卖票的方法后,遇到wait也不会抛出锁,而且会连续输出:“某个线程停止售票”?
      

  2.   

    1.p.name=getName();
    显示有问题,代码里只有一个p.多个Seller对象把多个name值赋值到同一个里面,显然是有问题的p.name仅仅保留了最后一次赋值过去的名称。你看到的输出,其实是错误的
      

  3.   

    其实抛出锁了,只是你的程序写法有问题,因为你有多个卖票线程,这些卖票线程都会输出“某线程停止售票”,只是这个某线程的名字被另一个线程修改了,所以看上去是同一个线程,你试试看以下改正后的结果,你就可以明白了
    //共享数据类
    class Producer{
        String name;
        int ticket=0;
        int i=0;
        //产票方法
        public synchronized void putTicket() throws InterruptedException{
            if(ticket<=0){
                ticket++;
                System.out.println("开始生产第"+ticket+"张票");
            }else{
                
                System.out.println("票有剩余,停止产票");
                notifyAll();
                wait();
            }
        }
        
        //买票方法
        public synchronized void getTicket() throws InterruptedException{
            if(ticket<=0){
                //System.out.println(name+"停止售票");
                System.out.println(Thread.currentThread().getName()+"停止售票");//改成这样你就清楚了
                notifyAll();
                wait();
            }else{
                ticket--;
                i++;
                //System.out.println(name+"出售第"+i+"张票");
                System.out.println(Thread.currentThread().getName()+"出售第"+i+"张票");            
            }
        }
        
    }
    //产票类
    class Department extends Thread{
        Producer p;
        public Department(Producer p){
            this.p=p;
        }
        
        public void run(){
            while(true){
                try {
                    Thread.sleep((int)(Math.random()*30*100));
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                try {
                    p.putTicket();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        
    }
    //买票类
    class Seller extends Thread{
        
        Producer p;
        public Seller(Producer p,String name){
            super(name);
            this.p=p;
            
        }
        
        public void run(){
            //p.name=getName();//这里的问题
            while(true){
                try {
                    Thread.sleep((int)(Math.random()*30*100));
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                try {
                    p.getTicket();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        
    }
    //测试类
    public class TicketTest {
        
        public static void main(String args[]){
            Producer p=new Producer();
            Department d=new Department(p);
            Seller s1=new Seller(p,"窗口A"); 
            Seller s2=new Seller(p,"窗口B");
            Seller s3=new Seller(p,"窗口C");
            Seller s4=new Seller(p,"窗口D");
            d.start();
            s1.start();
            s2.start();
            s3.start();
            s4.start();
        }}