第三部分 线程安全(3)——线程同步

 

当已经有线程在执行这段代码块时,其他的线程必须等待其执行完毕才能进入这段代码块——这就是所谓的线程同步。

一.单实例线程的同步锁

 

首先看个实例,由于缺少线程同步机制,导致线程执行结果的错误。

 

实例代码【TestSynchronizationUsingRunnable

 

 

 

运行结果:

ThreadA 共有元素:2

ThreadB 共有元素:2

 

造成这一结果的原因在于,当线程ThreadA 向列表中添加一个元素之后,线程ThreadB也向其中添加了一个元素,由此造成两个线程均认为列表中的元素个数为2,而事实上,在线程ThreadA完成添加之后列表中的元素个数只有1。 下面对代码进行修改,把注释部分去掉。

 

代码如下:

 

 

 

执行结果:

 

“synchronized(this)”中的this代表锁定的对象实际上是Runnable对象,而一旦锁定了Runnable对象,便实现了线程同步。

 

二.多实例线程的同步锁

 

上面说的是单实例,多线程,现在说多实例,多线程。多线程没有基于共同的线程对象,那么如何实现它们之间的同步呢?

首先看一下同步之前的代码【TestSynchronizationUsingThread】

 

 

执行结果:

 

ThreadA 最后一个元素:1

ThreadB 最后一个元素:1

 

 

执行结果:

ThreadA 最后一个元素:0

ThreadB 最后一个元素:1

 

至此,我们可以对同步锁做出一个定义:当线程执行到synchronized的时候,检查传入的实参对象,并得到该对象的锁旗标。如果得不到,那么线程就会被加入到一个与该对象的锁旗标相关联的等待线程池中,一直等到对象的锁旗标被归还,池中的等待线程就会得到该锁旗表,如何继续执行下去。当线程执行完成同步代码块,就会自动释放,它占有的同步对象的锁旗标。

 

三.线程死锁

 在启用同步锁机制后,有两种对象是需要避免的。一是无限等待,二是循环等待。都会导致线程死锁。

 

 

  1.无限等待:线程B等待线程A完成同步锁内的代码块后释放同步锁,然而线程A却陷入了死循环。导致无法释放同步锁,这将进一步导致线程B陷入无限等待。例如:

synchronized(this)

{

  while(true)

     {....}

}

  2. 循环等待:线程A锁住了对象1,等待对象2的释放,线程B锁住了对象2,等待对象1的释放,从而造成了死锁。

下面代码就是对死锁进一步的解释。

 

 

 

 

同步锁后的代码:

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cuiran

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值