黑马程序员-Java基础-多线程间通讯
2013-11-22 18:56
357 查看
---------------------
ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
* 线程间通讯:
* 其实就是多线程在操作同一个资源,但是操作的动作不同。
*
* wait:
* notify:
* notifyAll:
*都使用在同步中,因为要对持有监视器的线程操作,只有同步才有锁。
* Lock是从1.5之后的新特性,
* 提供了显式的锁机制,以及显示的锁对象 上的等待唤醒操作机制。
* 一个锁可以对应多个condition对象,以前锁只能对应一个对象,容易产生死锁。
* 将同步中的synchronized替换成了实现Lock操作。
* condition对象中有await(),signal,signalAll方法
* 将Object中的wait,notify,notifyAll替换。
* 该对象可以Lock锁进行获取。
* stop方法已经过时。
* 停止线程的原理:
* 停止线程,只要停止run结束。
* 开启多线程运行,运行代码通常是循环结构。
* 只要控制循环,就可以让run方法结束。也就是线程结束。
*
* 特殊情况:
* 当线程处于冻结状态,就不会读取到标记,那么线程就不会结束。
* 当没有指定的方式让冻结的线程恢复到运行状态时,这时需要对冻结进行清除。
* 强制让线程恢复到运行状态中来,这样可以操作标记让线程结束。
*
* Thread类提供了方法interrupt(),清除线程的冻结状态,然后利用标记flag结束线程。。
*为什么这些操作线程的方法要定义在Object类中呢?
*因为这些方法在操作同步中线程时,都必须要标识它们所操作线程中的锁。
*只有同一个锁上的被等待线程,可以被锁上notify唤醒。不可以对不同锁中的线程进行唤醒。
*也就是说,等待和唤醒必须是同一个锁。而锁可以是任意对象,所以可以被任意对象的方法定义在Object类中。
下面一生产者和消费者的例子说明线程间通讯。
方式一:使用Synchronized方式实现:代码如下:
----------------------
ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
* 线程间通讯:
* 其实就是多线程在操作同一个资源,但是操作的动作不同。
*
* wait:
* notify:
* notifyAll:
*都使用在同步中,因为要对持有监视器的线程操作,只有同步才有锁。
* Lock是从1.5之后的新特性,
* 提供了显式的锁机制,以及显示的锁对象 上的等待唤醒操作机制。
* 一个锁可以对应多个condition对象,以前锁只能对应一个对象,容易产生死锁。
* 将同步中的synchronized替换成了实现Lock操作。
* condition对象中有await(),signal,signalAll方法
* 将Object中的wait,notify,notifyAll替换。
* 该对象可以Lock锁进行获取。
* stop方法已经过时。
* 停止线程的原理:
* 停止线程,只要停止run结束。
* 开启多线程运行,运行代码通常是循环结构。
* 只要控制循环,就可以让run方法结束。也就是线程结束。
*
* 特殊情况:
* 当线程处于冻结状态,就不会读取到标记,那么线程就不会结束。
* 当没有指定的方式让冻结的线程恢复到运行状态时,这时需要对冻结进行清除。
* 强制让线程恢复到运行状态中来,这样可以操作标记让线程结束。
*
* Thread类提供了方法interrupt(),清除线程的冻结状态,然后利用标记flag结束线程。。
*为什么这些操作线程的方法要定义在Object类中呢?
*因为这些方法在操作同步中线程时,都必须要标识它们所操作线程中的锁。
*只有同一个锁上的被等待线程,可以被锁上notify唤醒。不可以对不同锁中的线程进行唤醒。
*也就是说,等待和唤醒必须是同一个锁。而锁可以是任意对象,所以可以被任意对象的方法定义在Object类中。
下面一生产者和消费者的例子说明线程间通讯。
方式一:使用Synchronized方式实现:代码如下:
package com.itheima.day12; /** * 生产者-消费者举例 * notifyAll适合于多个生产者和多个消费者的情况。实际中较为通用的方式。 * 对于多个生产者和消费者,为什么要定义while判断标记呢? * 原因:让被唤醒的线程再一次判断标记。 * 为什么定义notifyAll * 因为需呀唤醒对方线程,如果只用notify,容易出现只唤醒本方线程的情况,导致程序中的所有线程都等待。 */ public class ProducerConsumerDemo { public static void main(String[] args) { Resource r = new Resource(); Producer pro = new Producer(r); Consumer con = new Consumer(r); Thread t1 = new Thread(pro); Thread t2 = new Thread(pro); Thread t3 = new Thread(con); Thread t4 = new Thread(con); t1.start(); t2.start(); t3.start(); t4.start(); } } class Resource { private String name; private int count = 1; private boolean flag = false; public synchronized void set(String name) { while(flag) try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } this.name = name+"--"+count++; System.out.println(Thread.currentThread().getName()+"-生产者------"+this.name); flag = true; this.notifyAll(); } public synchronized void out() { while(!flag) try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"-消费者-"+this.name); flag = false; this.notifyAll(); } } class Producer implements Runnable { private Resource re; Producer(Resource re) { this.re = re; } public void run() { while(true) { re.set("+商品+"); } } } class Consumer implements Runnable { private Resource re; Consumer(Resource re) { this.re = re; } public void run() { while(true) { re.out(); } } } /*适合于消费者一个,生产者也是一个的情况 public class ProducerConsumerDemo { public static void main(String[] args) { Resource r = new Resource(); Producer pro = new Producer(r); Consumer con = new Consumer(r); Thread t1 = new Thread(pro); Thread t2 = new Thread(con); t1.start(); t2.start(); } } class Resource { private String name; private int count = 1; private boolean flag = false; public synchronized void set(String name) { if(flag) try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } this.name = name+"--"+count++; System.out.println(Thread.currentThread().getName()+"-生产者------"+this.name); flag = true; notify(); } public synchronized void out() { if(!flag) try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"-消费者-"+this.name); flag = false; notify(); } class Producer implements Runnable { private Resource re; Producer(Resource re) { this.re = re; } public void run() { while(true) { re.set("+商品+"); } } } class Consumer implements Runnable { private Resource re; Consumer(Resource re) { this.re = re; } public void run() { while(true) { re.out(); } } } */实现方式二:Lock锁实现线程间通讯
package com.itheima.day12; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * 生产者-消费者举例 * * Lock是从1.5之后的新特性, * 提供了显式的锁机制,以及显示的锁对象 上的等待唤醒操作机制。 * 一个锁可以对应多个condition对象,以前锁只能对应一个对象,容易产生死锁。 * * 将同步中的synchronized替换成了实现Lock操作。 * condition对象中有await(),signal,signalAll方法 * 将Object中的wait,notify,notifyAll替换。 * 该对象可以Lock锁进行获取。 * 在该示例中,实现了本方只唤醒对方的操作。 * */ public class LockProducerConsumerDemo { public static void main(String[] args) { Resource1 r = new Resource1(); Producer1 pro = new Producer1(r); Consumer1 con = new Consumer1(r); Thread t1 = new Thread(pro); Thread t2 = new Thread(pro); Thread t3 = new Thread(con); Thread t4 = new Thread(con); t1.start(); t2.start(); t3.start(); t4.start(); } } class Resource1 { private String name; private int count = 1; private boolean flag = false; private Lock lk = new ReentrantLock(); private Condition condition_pro = lk.newCondition(); // 一个锁可以对应多个condition对象。 private Condition condition_con = lk.newCondition(); public void set(String name) throws InterruptedException { lk.lock(); try{ while(flag) condition_pro.await();//t1 t2 this.name = name+"--"+count++; System.out.println(Thread.currentThread().getName()+"-生产者------"+this.name); flag = true; condition_con.signal(); }finally { lk.unlock();//释放锁的动作一定要执行,防止await产生异常造成死锁。 } } //t3 t4 public void out() throws InterruptedException { lk.lock(); try { while(!flag) condition_con.await(); System.out.println(Thread.currentThread().getName()+"-消费者-"+this.name); flag = false; condition_pro.signal(); } finally { lk.unlock(); } } } class Producer1 implements Runnable { private Resource1 re; Producer1(Resource1 re) { this.re = re; } public void run() { while(true) { try { re.set("+商品+"); } catch (InterruptedException e) { e.printStackTrace(); } } } } class Consumer1 implements Runnable { private Resource1 re; Consumer1(Resource1 re) { this.re = re; } public void run() { while(true) { try { re.out(); } catch (InterruptedException e) { e.printStackTrace(); } } } }
----------------------
ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
相关文章推荐
- 黑马程序员——JAVA基础之多线程的线程间通讯等
- 黑马程序员_Java基础:多线程总结
- 黑马程序员-Java语言基础– 多线程 第12天
- 黑马程序员——Java重点基础之多线程(三) 注意
- 黑马程序员_java基础多线程
- 黑马程序员_Java基础_多线程_11
- 黑马程序员--Java基础--06多线程
- Java基础多线程间通讯之多生产者、多消费者模式示例:
- 黑马程序员_Java基础_多线程1
- 黑马程序员——Java基础—多线程(一)
- 黑马程序员——java基础 多线程(复习)
- 黑马程序员_java基础加强之多线程
- 黑马程序员_java基础_多线程
- 黑马程序员--java基础--多线程
- 黑马程序员.Android攻城狮.JAVA基础.1.5.Java多线程
- 黑马程序员---Java基础---多线程
- 黑马程序员——Java基础--- 多线程
- 黑马程序员——Java基础---理解多线程
- 黑马程序员——Java基础---多线程
- 黑马程序员_Java多线程通信基础