黑马程序员--第十二天:线程间的通信
2013-06-18 16:20
176 查看
---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
//12-1_3 class Res { String name; String sex; boolean flag = false; } class Input implements Runnable { Res r = new Res(); Input(Res r){ this.r = r; } public void run(){ int y = 0; int x = 0; while(y<1000){ y++; x = (x + 1)%2; synchronized(new Object()){//只要是唯一的就可以,Input.class,OutPut.class,Res.class,Demo.class. if(r.flag) try{r.wait();}catch(Exception e){} if(x == 0){ r.name = "mike"; r.sex = "male";} else{ r.name = "丽丽"; r.sex = "女";} r.flag = true; r.notify(); } //System.out.println(x); //break; } } } class Output implements Runnable { Res r = new Res(); Output(Res r){ this.r = r; } public void run(){ int y =0; while(y<1000){ y++; synchronized(new Object()){//只要是唯一的就可以,Input.class,OutPut.class,Res.class,Demo.class. if(!r.flag) try{r.wait();}catch(Exception e){} System.out.println(r.name+"..."+r.sex); r.flag = false; r.notify(); } //break; } } } class Demo { public static void main(String[] args) { Res r = new Res(); new Thread(new Input(r)).start(); new Thread(new Output(r)).start(); System.out.println("Hello World!"); } } //notigyAll(); /* wait(); notify(); notifyAll(); 都使用在同步中,因为要对持有监视器(锁)的线程的操作 所以要使用在同步中,因为只有同步才具有锁。 为什么这些操作线程的方法要定义在Object的类中呢? 因为这些方法在操作同步中的线程时,都必须要标志他们所操作的线程持有的锁。 只有同一个锁上的被等待的线程,可以被同一个锁上的notify唤醒。 不可以对不同锁中的线程进行唤醒。 也就是说,等待和唤醒必须是同一个锁。 而锁可以是任意对象,所以可以被任意对象调用的方法调用Object中。 */ //12-4 class Res { private String name; private String sex; private boolean flag = false; public synchronized void set(String name,String sex){ if(flag) try{wait();}catch(Exception e){} this.name = name; this.sex = sex; flag = true; notify(); } public synchronized void Out(){ if(!flag) try{r.wait();}catch(Exception e){} System.out.println(r.name+"..."+r.sex); flag = false; notify(); } } class Input implements Runnable { Res r = new Res(); Input(Res r){ this.r = r; } public void run(){ int y = 0; int x = 0; while(y<1000){ y++; x = (x + 1)%2; if(x == 0) r.set("mike","male"); else r.set("丽丽","女"); } } } class Output implements Runnable { Res r = new Res(); Output(Res r){ this.r = r; } public void run(){ int y =0; while(y<1000){ y++; r.out(); } } } class Demo { public static void main(String[] args) { Res r = new Res(); new Thread(new Input(r)).start(); new Thread(new Output(r)).start(); System.out.println("Hello World!"); } } /*12-5 对于多个生产者和消费者, 为什么要定义while判断标记? 原因:让唤醒的线程再一次判断 为什么定义notifyAll? 因为要唤醒对方线程。 英文只用notify,容易出现只唤醒本方线程的情况。导致程序中的所以线程都等待。 */ class Resource { private String name; private int count = 1; private boolean flag = false; public synchronized void set(String name){ while(flag)//多个生产者与消费者的情况必须保证唤醒的线程再次判断flag try{wait();}catch(Exception e){} 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(Exception e){} System.out.println(Thread.currentThread().getName()+"...消费者...+++"+this.name); flag = false; this.notifyAll();// } } class Producer implements Runnable { private Resource res; Producer (Resource res){ this.res = res; } public void run(){ while (true) { res.set("product"); } } } class Consumer implements Runnable { private Resource res; Consumer (Resource res){ this.res = res; } public void run(){ while (true) { res.out(); } } } class ResDemo { public static void main(String[] args) { Resource r = new Resource(); new Thread(new Producer(r)).start(); new Thread(new Producer(r)).start(); new Thread(new Consumer(r)).start(); new Thread(new Consumer(r)).start(); System.out.println("Hello World!"); } } /*12-6 JDK5.0 (新特性) 提供了多线程升级解决方案。 将同步synchronized 替换成现实Lock操作。 将Object中wait,notify notifyAll,替换成了Condition对象。 该对象可以Lock锁进行获取。 该实例中,实现了本方只唤醒对方的操作。 */ import java.util.concurrent.locks.*; class Resource { private String name; private int count = 1; private boolean flag = false; private Lock lock = new ReentrantLock(); private Condition condition_pro = lock.newCondition(); private Condition condition_con = lock.newCondition(); public void set(String name)throws InterruptedException{ lock.lock(); try{ while(flag)//多个生产者与消费者的情况必须保证唤醒的线程再次判断flag condition_pro.wait(); this.name = name+"----"+count++; System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name); flag = true; condition_con.signal();//需要唤醒对方的线程。 }finally{ lock.unlock(); } } public void out() throws InterruptedException{ lock.lock(); try{ while(!flag)// condition_con.wait(); System.out.println(Thread.currentThread().getName()+"...消费者...+++"+this.name); flag = false; condition_pro.signal();// }finally{ lock.unlock();//lock 能个检测死锁。 } } } class Producer implements Runnable { private Resource res; Producer (Resource res){ this.res = res; } public void run(){ while (true) { try{ res.set("product");} catch(Exception e){} } } } class Consumer implements Runnable { private Resource res; Consumer (Resource res){ this.res = res; } public void run(){ while (true) { try{ res.out(); }catch(Exception e){} } } } class ResDemo { public static void main(String[] args) { Resource r = new Resource(); new Thread(new Producer(r)).start(); new Thread(new Producer(r)).start(); new Thread(new Consumer(r)).start(); new Thread(new Consumer(r)).start(); System.out.println("Hello World!"); } } /*12-7 stop 方法已过时。 如何停止线程? 只有一种,run方法结束。 开启多线程运行,运行代码通常是循环结构。 只要控制住循环,就可以让run方法结束。也就是线程结束。 特殊情况:当线程处于冻结状态。就不会读取到标记。那么线程就不会结束。 当没有指定的方式让冻结的线程恢复到运行状态时,就需要对冻结进行清除。 强制让线程恢复到运行状态中来。这样就可以操作标记让线程结束。 Thread类提供该方法是 interrupt(); */ class StopThread implements Runnable { private boolean flag = true; public synchronized void run(){//若 wait() 等的方法没有在synchronized 修饰区域, //编译可以通过,方法可以运行,当会抛出异常。 while(flag){ try { wait(); } catch (Exception e) { System.out.println(Thread.currentThread().getName()+"catch"); } System.out.println(Thread.currentThread().getName()+"...生产者."); } } public void changeFlag(){ flag = false; } } class StopDemo { public static void main(String[] args) { StopThread st = new StopThread(); Thread t1 = new Thread(st); Thread t2 = new Thread(st); t1.start(); t2.start(); System.out.println("Hello World!"); int num = 0; while (true) { if(num++ == 60){ /* //个人扩展的方法 synchronized(st){ st.notifyAll();//程序可以正常结束,不会产生异常。 }//------------ */ t1.setDeamon(true); t2.setDeamon(true);//守护线程,后台线程,在所以前台线程都结束是,自动结束后台线程。 t1.interrupt();//唤醒线程,抛出异常。 t2.interrupt(); st.changeFlag(); break; } System.out.println(Thread.current 4000 Thread().getName()+"..."+num); } } } /* 12-8_10 12-9 join方法 join: 当A线程执行到了B线程的 .join()方法,A就会等待,等B线程都执行完,A才会执行。 join可以用来临时加入线程执行。 12-10 优先级与yield方法: Thread.yield();//有助于平均 运行效果。临时释放执行权,减缓线程运行。 */ class StopThread implements Runnable { private boolean flag = true; public synchronized void run(){//若 wait() 等的方法没有在synchronized 修饰区域, //编译可以通过,方法可以运行,当会抛出异常。 while(flag){ try { wait(); } catch (Exception e) { System.out.println(Thread.currentThread().getName()+"catch"); } System.out.println(Thread.currentThread().toString()+"...生产者."); } } public void changeFlag(){ flag = false; } } class StopDemo { public static void main(String[] args) { StopThread st = new StopThread(); Thread t1 = new Thread(st); Thread t2 = new Thread(st); t1.start(); t1.setPriority(Thread.MAX_PRIORITY); t2.start(); System.out.println("Hello World!"); int num = 0; while (true) { if(num++ == 60){ /* //个人扩展的方法 synchronized(st){ st.notifyAll();//程序可以正常结束,不会产生异常。 }//------------ */ t1.setDeamon(true); t2.setDeamon(true);//守护线程,后台线程,在所以前台线程都结束是,自动结束后台线程。 t1.interrupt(); t2.interrupt(); t1.join();//主线程会等到t1 线程结束后在运行。 st.changeFlag(); break; } System.out.println(Thread.currentThread().getName()+"..."+num); } } }
---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
相关文章推荐
- 黑马程序员——>第十二天<多线程(线程间通信-守护线程)>
- 黑马程序员-19-java基础-多线程(2)-死锁与线程间通信(synchronized与Lock的区别及各自用法)
- 黑马程序员——多线程(线程安全、线程间通信、1.5中的Lock)总结2
- 黑马程序员_多线程的线程间通信学习笔记
- 黑马程序员——生产者消费者问题之线程间通信
- 黑马程序员-day12-多线程(线程间通信)
- 黑马程序员--java基础复习之多线程及线程间通信
- 第十二天-多线程(线程间通信)
- 黑马程序员—11—java基础:有关线程通信的学习笔记和学习心得体会
- 黑马程序员——多线程(线程间通信)
- 黑马程序员——多线程之线程间的通信
- 黑马程序员_线程间的通信
- 黑马程序员_JavaSE基础14 之 线程间通信 等待唤醒机制 多生产多消费者 ...
- 黑马程序员:线程间通信介绍:wait()、notify()、Lock、Condition等介绍
- 黑马程序员_<<线程间通信>>
- 黑马程序员_Java基础_线程间通信,生产者消费者案例,jdk1.5锁机制,守护线程
- 黑马程序员——多线程6:线程间通信
- 黑马程序员---多线程:线程间通信
- 黑马程序员——java基础日记——多线程(2)——线程间通信与JDK1.5新特性
- 黑马程序员自学笔记————多线程 线程间通信之生产者消费者问题;