标题:
Java中的多线程你只要看这一篇就够了(2)
[打印本页]
作者:
look_w
时间:
2018-12-15 13:27
标题:
Java中的多线程你只要看这一篇就够了(2)
内功心法:每个对象都有的方法(机制)synchronized, wait, notify 是任何对象都具有的同步工具。让我们先来了解他们
monitor
他们是应用于同步问题的人工线程调度工具。讲其本质,首先就要明确monitor的概念,Java中的每个对象都有一个监视器,来监测并发代码的重入。在非多线程编码时该监视器不发挥作用,反之如果在synchronized 范围内,监视器发挥作用。
wait/notify必须存在于synchronized块中。并且,这三个关键字针对的是同一个监视器(某对象的监视器)。这意味着wait之后,其他线程可以进入同步块执行。
当某代码并不持有监视器的使用权时(如图中5的状态,即脱离同步块)去wait或notify,会抛出java.lang.IllegalMonitorStateException。也包括在synchronized块中去调用另一个对象的wait/notify,因为不同对象的监视器不同,同样会抛出此异常。
再讲用法:
synchronized单独使用:
代码块:如下,在多线程环境下,synchronized块中的方法获取了lock实例的monitor,如果实例相同,那么只有一个线程能执行该块内容[url=]
[/url]
public
class
Thread1
implements
Runnable { Object lock;
public
void
run() {
synchronized
(lock){ ..
do
something } }}
[url=]
[/url]
直接用于方法: 相当于上面代码中用lock来锁定的效果,实际获取的是Thread1类的monitor。更进一步,如果修饰的是static方法,则锁定该类所有实例。
public
class
Thread1
implements
Runnable {
public
synchronized
void
run() { ..
do
something }}
synchronized, wait, notify结合:典型场景生产者消费者问题
[url=]
[/url]
/**
* 生产者生产出来的产品交给店员
*/
public
synchronized
void
produce() {
if
(
this
.product >=
MAX_PRODUCT) {
try
{ wait(); System.out.println(
"产品已满,请稍候再生产"
); }
catch
(InterruptedException e) { e.printStackTrace(); }
return
; }
this
.product++
; System.out.println(
"生产者生产第" +
this
.product + "个产品."
); notifyAll();
//
通知等待区的消费者可以取出产品了
}
/**
* 消费者从店员取产品
*/
public
synchronized
void
consume() {
if
(
this
.product <=
MIN_PRODUCT) {
try
{ wait(); System.out.println(
"缺货,稍候再取"
); }
catch
(InterruptedException e) { e.printStackTrace(); }
return
; } System.out.println(
"消费者取走了第" +
this
.product + "个产品."
);
this
.product--
; notifyAll();
//
通知等待去的生产者可以生产产品了
}
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/)
Powered by Discuz! 7.0.0