Java之线程4--synchronized线程同步

引入一个 场景:

 *一家包子店每天限量销售包子
 * 现在包子店还剩5个包子 
 * 张三和李四同时在不同窗口买包子,张三要买3个,李四也要买3个

Buy类用于展示购买结果

class Buy {
	public static int left = 5;
	/*
	 * @name 购买者姓名
	 * @num 购买包子数量
	 */
	public void buy_bread(String name, int num) {
			left = left - num;
			if (left < 0) {
				System.out.println(name + ",There's no engous bread left!");
				return;
			}
			try {
				Thread.sleep(1);
			} catch (InterruptedException e) {
			}
			System.out.println(name + " has bought " + num + " bread, there's " + left + " bread left");		

	}
}

Store类模拟场景中的故事

public class Store implements Runnable {
	static Buy buy = new Buy();
	public static void main(String[] args) {
		Store w = new Store();
		Thread t1 = new Thread(w) {
			@Override
			public void run() {
				// 打东边来了个张三,他要买3个包子
				buy.buy_bread(Thread.currentThread().getName(),3 );
			}
		};
		Thread t2 = new Thread(w) {
			@Override
			public void run() {
				// 打西边来了个李四,也要买3个包子
				buy.buy_bread(Thread.currentThread().getName(), 3);
			}
		};
		t1.setName("zhangsan");
		
		t2.setName("lisi");
		t1.start();
		t2.start();
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		
	}

}

运行结果

lisi,There's no engous bread left!
zhangsan has bought 3 bread, there's -1 bread left

 

按道理来讲,因为只有5个包子,两个人同时来买,每个人都买3个,必然是有一个人能够买到,另一个人买不到,最终还剩2个包子。但是结果为什么是李四一来就没有包子了,张三买了3个最终包子为负数了?

原因是张三先来买包子,它买了包子还没来得及输出购买结果的时候(此时left已经等于2),线程睡着了,所以方法执行被打断了(Buy类中的Thread.sleep(1);)。即使不睡着也可能被打断,只是为了更好的模拟。这时候李四来了,先判断left-3,发现小于0,告诉李四包子不够了,直接return,李四的线程就结束了。又切换到张三的线程,输出left,因为left刚刚被李四修改过了,所以是-1。

那么,有什么办法让张三买包子直到输出完状态,其他人不得在中途抢占资源呢?这就引入了synchronized,synchronized可以锁定当前代码段,保证现有资源不被抢占,直到执行完锁定的片段

class Buy {
	public static int left = 5;
	/*
	 * @name 购买者姓名
	 * @num 购买包子数量
	 */
	public void buy_bread(String name, int num) {
		synchronized (this) {
			left = left - num;
			if (left < 0) {
				System.out.println(name + ",There's no engous bread left!");
				return;
			}
			try {
				Thread.sleep(1);
			} catch (InterruptedException e) {
			}
			System.out.println(name + " has bought " + num + " bread, there's " + left + " bread left");
		}

	}
}

结果输出:

lisi has bought 3 bread, there's 2 bread left
zhangsan,There's no engous bread left!

现在终于能正常买包子了!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值