实现司机售票员线程同步模式,比较简单,通俗易懂。
售票员活动:关闭车门
司机的活动:启动车子
司机的活动:正常行驶;售票员活动:售票
司机的活动:到站停车;
售票员活动:打开车门;
pv操作实现
driver(){ while(true){ P(driver); start(); driving(); stop(); V(Seller); } } seller(){ while(true){ close(door); V(Driver); sell(); P(Seller); open(door); } }
很容易看出上述存在死锁,因为如果seller执行完V(Driver)之后Driver还没有执行到P(Driver),那么当Driver执行到P(Driver)之后则会挂起,而Seller到了P(Seller)之后也同样会挂起,因此死锁产生。
死锁产生的原因是V操作的信号被忽略了。因此只要保持住该信号就可以唤醒Driver。因此java代码对其的改进如下所示:
package concurrency; import java.security.interfaces.DSAKey; import java.util.Random; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class DriverAndSeller { Object driver = new Object(); Object seller = new Object(); int driverNotify = 0; int sellerNotify = 0; class Driver implements Runnable{ public void run(){ Random random = new Random(47); while(true){ try{ synchronized (driver) { if(driverNotify==0) driver.wait(); driverNotify--; } System.out.println("[Driver]: Starting..."); Thread.sleep(random.nextInt(1000)+1000); System.out.println("[Driver]: Runing..."); Thread.sleep(random.nextInt(6000)); System.out.println("[Driver]: Stop..."); synchronized (seller) { sellerNotify++; seller.notify(); } }catch (InterruptedException e) { e.printStackTrace(); } } } } class Seller implements Runnable{ public void run(){ Random random = new Random(47); while(true){ try{ System.out.println("[Seller]: Closing door..."); synchronized (driver) { driverNotify++; driver.notify(); } Thread.sleep(random.nextInt(1000)+500); System.out.println("[Seller]: Selling tickets..."); Thread.sleep(random.nextInt(1000)+5000); synchronized (seller) { if(sellerNotify==0) seller.wait(); sellerNotify--; } System.out.println("[Seller]: Opening door..."); Thread.sleep(random.nextInt(300)+300); }catch (InterruptedException e) { e.printStackTrace(); } } } } public static void main(String[] args){ DriverAndSeller das = new DriverAndSeller(); ExecutorService es = Executors.newFixedThreadPool(2); es.execute(das.new Driver()); es.execute(das.new Seller()); } }
所得的结果是:
[Seller]: Closing door... [Driver]: Starting... [Seller]: Selling tickets... [Driver]: Runing... [Driver]: Stop... [Seller]: Opening door... [Seller]: Closing door... [Driver]: Starting... [Seller]: Selling tickets... [Driver]: Runing... [Driver]: Stop... [Seller]: Opening door... [Seller]: Closing door... [Driver]: Starting... [Seller]: Selling tickets... [Driver]: Runing... [Driver]: Stop... [Seller]: Opening door... [Seller]: Closing door... [Driver]: Starting... [Seller]: Selling tickets...