多线程中wait、notify理解
2015-09-17 20:57
344 查看
实在惭愧,java开发多年,多线程运用一直不多,该知识点理解也不够,不怎么会用。赶上使用多线程 生产者、消费者模式,学习下该知识点。
synchronized 获取锁
wait 阻塞本线程,释放对象锁。该线程会在该代码处阻塞,不往下执行。
notify 释放对象锁,通知其他被阻塞的线程可以被唤醒。
Thread.sleep()与Object.wait()二者都可以暂停当前线程,释放CPU控制权,主要的区别在于Object.wait()在释放CPU同时,释放了对象锁的控制。
IllegalMonitorStateException异常发生是由于程序员没有注意notify(),notify(),wait()方法的使用条件,没有真正理解线程同步机制。如果当前的线程不是此对象锁的所有者,却调用该对象的notify(),notify(),wait()方法时抛出该异常。个人暂时理解为若线程没有持有任何锁,而调用这几个方法,会出现该异常。
synchronized 获取锁
wait 阻塞本线程,释放对象锁。该线程会在该代码处阻塞,不往下执行。
notify 释放对象锁,通知其他被阻塞的线程可以被唤醒。
Thread.sleep()与Object.wait()二者都可以暂停当前线程,释放CPU控制权,主要的区别在于Object.wait()在释放CPU同时,释放了对象锁的控制。
IllegalMonitorStateException异常发生是由于程序员没有注意notify(),notify(),wait()方法的使用条件,没有真正理解线程同步机制。如果当前的线程不是此对象锁的所有者,却调用该对象的notify(),notify(),wait()方法时抛出该异常。个人暂时理解为若线程没有持有任何锁,而调用这几个方法,会出现该异常。
package socket; public class Producer2 extends Thread { public class Producer extends Thread { private Share shared; private int number; public Producer(Share s, int number) { shared = s; this.number = number; } public void run() { for (int i = 0; i < 10; i++) { System.out.println("[00]"); shared.put(i); System.out.println("生产者" + this.number + " 输出的数据为:" + i); try { sleep((int) (Math.random() * 100));//这里一定要加,否则(注释掉sleep代码)消费者可能会暂时取不到cpu控制权,而没办法打印出信息。而此时消费者get()方法中已经执行notify方法,导致生产者被唤醒,继续生产执行put(),给人误导没有消费。实际已经消费而只是未打印而已。 } catch (InterruptedException e) { } System.out.println("[000]"); } } } // 共享资源对象 public class Share { private int contents; private boolean available = false; public synchronized int get() { System.out.println("[1]"); if (available == false) { try { System.out.println("[2]"); wait(); System.out.println("[3]"); } catch (InterruptedException e) { } } available = false; System.out.println("[4]"); notify();// 通知其他使用该对象的线程,你们可以在适当的时间被唤醒了。只要我锁一释放(synchronized方法体执行完),其他线程就有被唤醒的可能,就有可能把锁抢过去执行了。 System.out.println("[5]"); return contents; } public synchronized void put(int value) { System.out.println("[6]"); if (available == true) { try { System.out.println("[7]"); wait();// 我不使用该对象了,本线程睡觉了,现在是其他对象被唤醒的时机,你们可以在被wait的地方继续执行了 System.out.println("[8]"); } catch (InterruptedException e) { } } available = true; System.out.println("[9]"); notify();//这里也要加,原因是,用于唤醒其他线程,不加的话,在本线程睡觉后,消费者线程不被唤醒,生产者线程唤醒其他线程的notify方法没有机会执行,那生产者线程会一直睡大觉了。 System.out.println("[10]"); contents = value; } } // 消费者程序 public class Consumer extends Thread { private Share shared; private int number; public Consumer(Share s, int number) { shared = s; this.number = number; } public void run() { int value = 0; for (int i = 0; i < 10; i++) { System.out.println("[11]"); value = shared.get(); System.out.println("消费者" + this.number + " 得到的数据为:" + value); } } } // 主程序 public static void main(String[] args) { Producer2 test = new Producer2(); Share s = test.new Share(); Producer p = test.new Producer(s, 1); Consumer c = test.new Consumer(s, 1); p.start(); try { Thread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } c.start(); } }
相关文章推荐
- 有意练习--Rails RESTful(一)
- Master-Detail 用户界面
- 利用pthread_cond_timedwait实现sleep
- LeetCode 220. Contains Duplicate III
- httpd: Could not reliably determine the server's fully qualified domain name
- Hibernate4中使用getCurrentSession报Could not obtain transaction-synchronized Session for current thread
- 使用mdadm快速创建RAID5
- Halo,Halo 2游戏的人工智能设计讲座
- The Beauty of Capturing Faces: Rating the Quality of Digital Portraits
- Shallow heap & Retained heap
- Grails开源框架Note
- HDU 1022 Train Problem I(用栈模拟火车出入,看能否由初始顺序到达目标顺序)
- Boost库安装与使用 http://blog.csdn.net/cybertan/article/details/5770227
- 开源C/C++网络库比较 http://blog.csdn.net/langeldep/article/details/6976120
- ubuntu重啟網卡提示"Job failed while stopping"解決方法!【参考别人的信息】
- aidl理解
- 打开IDEA时报错“Failed to create JVM: error code -6”
- 【Code Forces 320A】【二进制拆分】Raising Bacteria 细胞繁殖 每天倍增
- CodeForces 579A - Raising Bacteria
- 音乐播放器-MainFragment分析1