线程同步 wait()、notify()

线程安全

很重要的概念。
多线程访问同一段代码,不会产生不确定的结果。则可以说这段代码是线程安全的。

常用方法

调用 sleep()的时候,锁并没有被释放,调用yield()也属于这种情况;而wait()方法会将锁释放。
只能在同步控制方法或同步控制块里面调用 wait()、notify()、notifyAll()。如果在非同步控制块中调用这些方法,能通过编译但运行会出错,得到IllegalMonitorStateException异常。
当调用某个ExecutorService的shutdownNow()时,它会调用 所有 由它控制的 线程的interrupt()。

Thread. yield()告诉java线程调度器“重要的部分我已经完成,此刻可以将我挂起,切换给其他线程执行”。这个函数可用可不用,但用了它更容易按照自己的掌控去切换线程,从而验证一些东西。

调用 wait()时,执行两个动作:挂起线程,释放锁。
别的地方调用notifyAll(),将唤醒wait()所挂起的线程。在线程继续运行之前将重新获得上次wait()调用时释放的锁。

使用 notify()时,在众多等待同一个锁的任务中只有一个会被唤醒。
notifyAll()唤醒所有等待同一个锁的任务。注意,这并不意味着在程序的任何地方,任何被wait()挂起的线程都会被唤醒,。当notifyAll()因为某个特定锁而被调用时,只有等待这个锁的任务才会被唤醒。

微笑打蜡、抛光在多个线程中交替进行。
需要一个状态切换的标志位,两对wait()、notify()操作。
一:Thinking in  Java 的例子
      
      
//: concurrency/waxomatic/WaxOMatic.java
// Basic task cooperation.
import java.util.concurrent.* ;

class Car {
private boolean waxOn = false ; //true表示打完蜡该抛光了
public synchronized void waxed () { // 已打蜡,可以抛光了
waxOn = true ;
System . out . println ( "waxed!" );
notifyAll ();
}
public synchronized void buffed () { // 已抛光,(下辆车)可以打蜡啦
waxOn = false ;
System . out . println ( "buffed!" );
notifyAll ();
}
public synchronized void waitForWaxing () //已打蜡情况下返回
throws InterruptedException {
while ( waxOn == false )
wait ();
}
public synchronized void waitForBuffing () //已抛光情况下返回
throws InterruptedException {
while ( waxOn == true )
wait ();
}
}

class Wax implements Runnable {
private Car car ;
public Wax ( Car c ) { car = c ; }
public void run () {
try {
while (! Thread . interrupted ()) {
TimeUnit . MILLISECONDS . sleep ( 200 );
car . waxed ();
car . waitForBuffing ();
}
} catch ( InterruptedException e ) {
System . out . println ( "Exiting via interrupt" );
}
System . out . println ( "Ending Wax On task" );
}
}

class Buff implements Runnable {
private Car car ;
public Buff ( Car c ) { car = c ; }
public void run () {
try {
while (! Thread . interrupted ()) {
car . waitForWaxing ();
TimeUnit . MILLISECONDS . sleep ( 200 );
car . buffed ();
}
} catch ( InterruptedException e ) {
System . out . println ( "Exiting via interrupt" );
}
System . out . println ( "Ending Wax Off task" );
}
}

public class WaxOMatic {
public static void main ( String [] args ) throws Exception {
Car car = new Car ();
ExecutorService exec = Executors . newCachedThreadPool ();
exec . execute ( new Buff ( car ));
exec . execute ( new Wax ( car ));
TimeUnit . SECONDS . sleep ( 2 ); // Run for a while...
exec . shutdownNow (); // Interrupt all tasks
}
} /*
waxed!
buffed!
waxed!
buffed!
waxed!
buffed!
waxed!
buffed!
waxed!
buffed!
Exiting via interrupt
Ending Wax On task
Exiting via interrupt
Ending Wax Off task
*/
      
      
调试时可以看到有三个线程,很直观。

 
            
            
//wait() notify()全放在Car类中处理
import java.util.concurrent.* ;
class Car {
private boolean waxOn = false ; // true表示打完蜡该抛光了
public synchronized void wax () throws InterruptedException {
while ( waxOn == true )
wait ();
TimeUnit . MILLISECONDS . sleep ( 100 );
waxOn = true ;
System . out . println ( "waxed!" );
notifyAll ();
}
public synchronized void buff () throws InterruptedException {
while ( waxOn != true )
wait ();
TimeUnit . MILLISECONDS . sleep ( 100 );
waxOn = false ;
System . out . println ( "buffed!" );
notifyAll ();
}
}
class Wax implements Runnable {
private Car car ;
public Wax ( Car car ) {
this . car = car ;
}
public void run () {
try {
while (! Thread . interrupted ()) {
car . wax ();
}
} catch ( InterruptedException e ) {
System . out . println ( "Wax Exiting via interrupt" );
}
}
}
class Buff implements Runnable {
private Car car ;
public Buff ( Car car ) {
this . car = car ;
}
public void run () {
try {
while (! Thread . interrupted ()) {
car . buff ();
}
} catch ( InterruptedException e ) {
System . out . println ( "Buff Exiting via interrupt" );
}
}
}
public class WaxOMatic {
public static void main ( String [] args ) throws Exception {
ExecutorService exec = Executors . newCachedThreadPool ();
Car car = new Car ();
exec . execute ( new Buff ( car ));
exec . execute ( new Wax ( car ));
TimeUnit . SECONDS . sleep ( 1 ); // Run for a while...
exec . shutdownNow (); // Interrupt all tasks
}
}
/*
waxed!
buffed!
waxed!
buffed!
waxed!
buffed!
waxed!
buffed!
waxed!
buffed!
Wax Exiting via interrupt
Buff Exiting via interrupt
*/
 来自CODE的代码片
全放在Car类中处理.java

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值