Java中的线程同步技术

原创 2015年07月09日 17:08:23

Java中的线程同步有几种方式,synchronized关键字和wait(),notify()下面就来对这两种方式展开描述一下:

synchronized关键字可以用于方法和代码块,若用于方法,默认是对当前实例加锁。而用于代码块时可以指定加锁对象(或者Class),这种加锁方式非常简单,而且一般情况下效率也不差。但是要

sychronized和wait()/notify方法的关系是什么呢?简而言之:synchronized可以单独存在,而wait()/notify()必须在synchronized代码块中间。wait()/notify()/notifyAll()

调用object.wait()方法后该线程进入对象的wait set,放弃线程被调度执行的机会,直到如下情形发生:

1.其它线程调用notify/notifyAll方法。当调用notify使一个线程获得竞争CPU调度的机会,其它线程继续在wait set中继续等待;调用notifyAll()时所有线程逐渐离开wait set,但是同一时间只能有一个线程拥有monitor,所以此时该线程也是竞争CPU调度,线程状态为BLOCKED。

2.其它线程中断该线程thread.interrupt(),被中断线程的wait方法将会抛出中断异常,但并不会立刻抛出异常,会开始竞争CPU调度,如果获得执行则获得当前对象的锁并抛出异常

3.若在wait(long timeout)参数中设置了超时时间,则当超时时间到达(进入BLOCKED状态)也会竞争该同步锁,先获得同步锁的线程会先被执行。


lock的几个区域


若线程在请求而且从未获得过锁就进入entryset,当线程获得锁后又执行了object.wait()就进入waitset


WAITING (on object monitor)说明线程已经进入synchronized块

waiting for monitor entry [0x00007fd4f8684000]:正在等待进入entryset,其中0x00007fd4f8684000为线程栈起始地址

 in Object.wait():正在等待进入waitset

Waiting on condition:等待资源()

线程有如下几个状态:
NEW:线程被创建但是还没有被执行

RUNNABLE:线程正在占用cpu并且在执行任务

BLOCKED:线程为了获得监视器需要等待其他线程释放锁

WAITING:调用了wait,join,park方法使线程等待-无限期等待

TIMED_WAITING:调用了sleep,wait,join,park方法使线程等待--有限期等待

 

线程的状态装换图:

Blocked:

1.对于进入了同步块并且wait已经到达了指定等待时间的线程将会进入BLOCKED状态,线程信息如下:

"wait-thread3" prio=6 tid=0x0000000008ef8800 nid=0x87d8 waiting for monitor entry [0x00000000097ef000]
   java.lang.Thread.State: BLOCKED (on object monitor)
 at com.csii.parent.WaitRunner.run(WaitRunner.java:12)
 - waiting to lock <0x00000000ff62c528> (a java.lang.Object)
 at java.lang.Thread.run(Unknown Source)

   Locked ownable synchronizers:
 - None

线程由始至终都没有获得过锁

2.对于等待进入同步块的进程也处于BLOCKED状态

"wait-thread2" prio=6 tid=0x0000000008116800 nid=0x712c waiting for monitor entry [0x0000000008def000]
   java.lang.Thread.State: BLOCKED (on object monitor)
 at java.lang.Object.wait(Native Method)
 - waiting on <0x00000000ff62c528> (a java.lang.Object)
 at com.csii.parent.WaitRunner.run(WaitRunner.java:15)
 - locked <0x00000000ff62c528> (a java.lang.Object)
 at java.lang.Thread.run(Unknown Source)

   Locked ownable synchronizers:
 - None

"wait-thread1" prio=6 tid=0x0000000008115800 nid=0x7e84 waiting for monitor entry [0x0000000008cef000]
   java.lang.Thread.State: BLOCKED (on object monitor)
 at java.lang.Object.wait(Native Method)
 - waiting on <0x00000000ff62c528> (a java.lang.Object)
 at com.csii.parent.WaitRunner.run(WaitRunner.java:15)
 - locked <0x00000000ff62c528> (a java.lang.Object)
 at java.lang.Thread.run(Unknown Source)

   Locked ownable synchronizers:
 - None

可以看到线程先是得到了锁,后来又释放了锁

版权声明:本文为博主原创文章,未经博主允许不得转载。

【java并发】传统线程同步通信技术

先看一个问题: 有两个线程,子线程先执行10次,然后主线程执行5次,然后再切换到子线程执行10,再主线程执行5次……如此往返执行50次。   看完这个问题,很明显要用到线程间的通信了, 先分析一下...
  • eson_15
  • eson_15
  • 2016年05月29日 11:50
  • 5437

windows线程同步的总结

一 线程 1)如果你正在编写C/C++代码,决不应该调用CreateThread。相反,应该使用VisualC++运行期库函数_beginthreadex,退出也应该使用_endthreadex...
  • peter_teng
  • peter_teng
  • 2013年09月06日 15:57
  • 6700

《Java多线程编程核心技术》推荐

写这篇博客主要是给猿友们推荐一本书《Java多线程编程核心技术》。之所以要推荐它,主要因为这本书写得十分通俗易懂,以实例贯穿整本书,使得原本抽象的概念,理解起来不再抽象。只要你有一点点Java基础,你...
  • u013142781
  • u013142781
  • 2016年03月04日 21:35
  • 18997

java并发-多线程之传统线程同步通信技术(4)

首先介绍几个概念:   这些方法都是Object的方法,并不是线程的方法! wait()方法     wait()方法使得当前线程必须要等待,等到另外一个线程...
  • fangqun663775
  • fangqun663775
  • 2018年01月03日 14:36
  • 12

JAVA 并发编程-线程同步通信技术(Lock和Condition)(十)

在之前的博客中已经介绍过线程同步通信技术《JAVA 并发编程-传统线程同步通信技术(四)》,上篇是使用的synchronized,wait,notify来实现,今天我们使用的是Lock和Conditi...
  • hejingyuan6
  • hejingyuan6
  • 2015年08月01日 10:01
  • 2131

黑马程序员---Java中传统线程同步通信技术

Object的Wait方法 方法签名:public final void wait()throws InterruptedException 导致当前线程等待直到另一个线程在这个对象上调用not...
  • ajiebcd
  • ajiebcd
  • 2015年06月25日 18:00
  • 233

JAVA 并发-线程同步通信技术(Lock和Condition)(10)

在之前的博客中已经介绍过线程同步通信技术《JAVA 并发-多线程传统线程同步通信技术(4)》,上篇是使用的synchronized,wait,notify来实现,今天我们使用的是Lock和Condit...
  • fangqun663775
  • fangqun663775
  • 2018年01月04日 16:39
  • 42

黑马程序员—java技术blog—第十五篇线程同步机制概述与简单应用

------- android培训、java培训、期待与您交流! ---------- 同步机制的实现方式:  * 1, 同步代码块  * 格式:  * synchronized(锁对...
  • wuyan242
  • wuyan242
  • 2015年09月27日 16:36
  • 226

java多线程之传统线程同步通信技术

wait和notify实例 子线程循环10次,主线程循环100次。接着子线程循环10次,主线程循环100次。如此循环50次。摘自张孝祥老师线程视频源码。 package javaplay.thread...
  • John8169
  • John8169
  • 2016年11月18日 19:25
  • 246

04_张孝祥_Java多线程_传统线程同步通信技术

一个主线程,一个子线程。子线程循环5次,接着换主线程循环10次,接着又回到子线程循环15次,接着再回到主线程又循环10次,如此循环10次...
  • kanbuqinghuanyizhang
  • kanbuqinghuanyizhang
  • 2017年12月16日 12:53
  • 35
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java中的线程同步技术
举报原因:
原因补充:

(最多只允许输入30个字)