在学习多线程同步问题的时候,经常使用多窗口同时买票的例子进行理解学习
当while(true)不在同步函数内部时:3个窗口交替卖票
while(true)不在同步代码块中:当窗口一获取到CPU执行权后,进入while(true)语句,执行同步方法,然后执行sleep方法,进程堵塞,假设此时窗口3进程获取到CPU执行权,进入while(true)语句,执行ticket.sale()同步方法,但是由于未获取到同步锁(窗口一线程执行的是sleep方法,不会释放锁对象)只能进入堵塞状态,当窗口1自动苏醒后继续执行sleep方法后的代码(卖票操作),执行完卖票操作后同步方法就结束了,释放了同步锁,此时多个线程之间竞争这个锁资源,此时如果窗口三获取到锁资源后就能执行卖票操作,执行完卖票操作后同样会释放锁资源。
当while(true)在同步函数中时:就只是一个窗口卖票
当while(true)在同步函数内部时,while(true)这个循环语句也成为了共享资源。虽然窗口一线程执行了sleep方法释放了CPU的执行权,但是由于未释放锁,导致窗口二三的线程虽然获取到CPU的执行权,但是无法获取到共享锁,进而无法操作共享资源(就是这儿的票,while(true))。又因为同步方法中卖票是在while(true中)执行的,导致该线程一直执行卖票直到票数为0为止。
只有一个窗口卖票的核心原因:while(true)循环会不断去执行卖票动作。当sleep函数结束当前线程自动苏醒(其他线程由于未获取到共享锁而进入堵塞状态,窗口一获取到CPU执行权),执行sleep函数后的代码,即卖票操作,执行完后并未退出同步函数,而是执行while(true)这个循环语句。导致其他线程根本无法获取到锁。