synchronized , wait() , notify() and notifyAll()
2015-07-25 22:21
639 查看
!!!!!!!!!!........................................
这三个东西,很容易,也很容易理解,几句话就轻松搞定了。
synchronized : 同一时刻只能有一个对象持有锁!
wait() : 当前线程会进入阻塞状态,并放弃锁
notify() :则会叫醒某一个线程
notifyAll():会叫醒所有线程
可是上面的理解对吗?
至少最后两个是错的。我原以为自己掌握的还好,可是今天遇到的这些状况却让我
不能自信的作出解释。
先看synchronized:
看下面这个例子,如果直接像下面一样通过一个SynTest对象调用,那么start这个锁就跟没加一样!
其实这个原因很简单,加锁的对象只能在一处使用,不管你是不是加锁对象本身,t1就是那个加锁的对象,它拥有那个锁,你可以无限的
调用它的加锁方法。
在看wait()和notify() / notifyAll() :
这两个东西我是误区颇深啊!
就像下面的代码,我还在一直想着,最后能够把所有的线程都唤醒了..
首先第一点,这两个东西必须方法在同步代码中,你可以给方法加synchronized 或者给 代码块加!
然后就是notify/notifyAll , 不是 A.notify() 或者 A.notifyAll() 就会把 B线程唤醒!!!!!
它是与对象挂钩,那个对象notify就只能notify那些等待这个对象控制权的线程!!!!
关于notify()/notifyAll()还要注意下下面这种情形:
当调用完了notify() / notifyAll() 的时候,并不等于等待线程就会立马运行,只有等调用完notify()或者notifyAll()
并退出synchronized块,释放对象锁后,其余线程才可获得锁执行。就像下面的例子,虽然调用了notifyAll()可是
线程阻塞在了,只有等他醒来,等待线程才能重新获得锁。
这篇博客 : notify / notifyAll / wait
这三个东西,很容易,也很容易理解,几句话就轻松搞定了。
synchronized : 同一时刻只能有一个对象持有锁!
wait() : 当前线程会进入阻塞状态,并放弃锁
notify() :则会叫醒某一个线程
notifyAll():会叫醒所有线程
可是上面的理解对吗?
至少最后两个是错的。我原以为自己掌握的还好,可是今天遇到的这些状况却让我
不能自信的作出解释。
先看synchronized:
看下面这个例子,如果直接像下面一样通过一个SynTest对象调用,那么start这个锁就跟没加一样!
其实这个原因很简单,加锁的对象只能在一处使用,不管你是不是加锁对象本身,t1就是那个加锁的对象,它拥有那个锁,你可以无限的
调用它的加锁方法。
public class SynTest { public static void main(String[] args) { SynTest t1 = new SynTest(); for(int i = 0 ; i < 10; i++) { A a = t1.create(); t1.start(a); } } A create() { A a = new A(); return a; } class A implements Runnable { // SynTest t ; @Override public void run() { test(); // t.test(); (这里test加了synchronized) } // A(SynTest t) { // this.t = t; // } } public void test () { System.out.println(this); try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized void start(Runnable a) { new Thread(a).start(); } }
在看wait()和notify() / notifyAll() :
这两个东西我是误区颇深啊!
就像下面的代码,我还在一直想着,最后能够把所有的线程都唤醒了..
public class Test { public static void main(String[] args) throws InterruptedException { init(); while(!conns.isEmpty()) { Conn conn = conns.remove(0); conn.start(); Thread.sleep(100); } } static List<Conn> conns = new ArrayList<Conn> (); static void init() { conns.add(new Conn()); conns.add(new Conn()); conns.add(new Conn()); } static class Conn extends Thread { @Override public void run() { try { send(); response(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " get response" ); } public synchronized void send() throws InterruptedException { if(!conns.isEmpty()) { System.out.println(Thread.currentThread().getName() + " send A to Server"); wait(); } else { response(); } } public synchronized void response() { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } notifyAll(); } } }
首先第一点,这两个东西必须方法在同步代码中,你可以给方法加synchronized 或者给 代码块加!
然后就是notify/notifyAll , 不是 A.notify() 或者 A.notifyAll() 就会把 B线程唤醒!!!!!
它是与对象挂钩,那个对象notify就只能notify那些等待这个对象控制权的线程!!!!
如果对象调用了wait方法就会使持有该对象的线程把该对象的控制权交出去,然后处于等待状态。 如果对象调用了notify方法就会通知某个正在等待这个对象的控制权的线程可以继续运行。 如果对象调用了notifyAll方法就会通知所有等待这个对象控制权的线程继续运行。
关于notify()/notifyAll()还要注意下下面这种情形:
当调用完了notify() / notifyAll() 的时候,并不等于等待线程就会立马运行,只有等调用完notify()或者notifyAll()
并退出synchronized块,释放对象锁后,其余线程才可获得锁执行。就像下面的例子,虽然调用了notifyAll()可是
线程阻塞在了,只有等他醒来,等待线程才能重新获得锁。
synchronized (flag) { flag = "true"; flag.notifyAll(); try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } }
这篇博客 : notify / notifyAll / wait
相关文章推荐
- Climbing Stairs
- strcpy,strncpy http://blog.csdn.net/shutear/article/details/8256096
- int main(int argc, char*argv[])
- 2015 Multi-University Training Contest 2 hdu 5308 I Wanna Become A 24-Point Master
- ECHOSRV.C中的main()设立一个 I/O completion port
- 【bzoj4152】 AMPPZ2014The Captain 最短路
- 一刀斩 :“SVN” failed to start 服务启动失败
- UVA - 10976 Fractions Again?!
- centos中w使用smbclient连接window出现:session setup failed: NT_STATUS_LOGON_FAILURE
- 二分搜索 HDOJ 2675 Equation Again
- 模拟器报Installation error: INSTALL_FAILED_CONTAINER_ERROR解决方法
- hdoj 2647 N!Again
- 人工智能的策略,如果国家优先发展”梦想成真”?
- Linux中的文件描述符与打开文件之间的关系 :http://blog.csdn.net/cywosp/article/details/38965239
- 关于Flash中的黑白棋AI编写心得
- Snail—OC学习之类别Category
- [leetcode ]220.Contains Duplicate III
- Snail—OC学习之空变量的表示
- Snail—OC学习之NSNumber
- Snail—OC学习之日期NSDate