Java 多线程编程--线程同步二(票数问题分析)

    前一章讲解了线程不一样步带来的问题,最后也给你们留下了一个思考,下面是对该问题的分析。bash

@Override
    public void run(){
        String windowName=Thread.currentThread().getName();
        while(ticket.count>0){
            synchronized (ticket) {
                    ticket.count--;
                    System.out.println(windowName + "卖出一张票 剩余票数" + ticket.count);
            }
        }
    }
}
复制代码

    如上所示,该代码的逻辑是经过对票数的数量进行判断是否结束当前线程。问题就出在循环判断这里。     A和B两个线程同时到达while语句,会对ticket数量进行判断。若是数量大于0,则进入循环对ticket变量进行操做。ide

    当ticket值为1,A和B两个线程都运行到while语句,会发现条件知足,因而都进入了while循环体。到达synchronized语句,这时A和B两个线程发生竞争关系,争夺ticket对象锁。假设A线程得到对象锁,那么B线程只能阻塞在synchronized(ticket)这里。A线程继续执行,对ticket进行减1操做,这时ticket值为0。代码执行完毕后,A线程释放锁,B取得ticket对象锁,开始对ticket进行减1操做,但此时ticket值为0,再继续操做就变成了-1。因此要想获得正确的结果,就得在对ticket进行操做前再判断一次,修改后的代码以下:spa

@Override
    public void run(){
        String windowName=Thread.currentThread().getName();
        while(ticket.count>0){
            synchronized (ticket) {
                if(ticket.count>0) {
                    ticket.count--;
                    System.out.println(windowName + "卖出一张票 剩余票数" + ticket.count);
                }
            }
        }
    }
}
复制代码
相关文章
相关标签/搜索