Java基础---第十二天 多线程

一、线程间的通信

三、线程间通信-等待唤醒机制
    1、wait(),notify(),notifyAll(),都使用在同步中,因为要对持有监视器(锁)的线程操作。所以要使用在同步中,因为只有同步才具有锁。
    2、为什么这些操作线程的方法要定义Object类中呢?因为这些方法在操作同步中,线程,都必须要表示它们所操作线程只有的锁,只有同一个锁上的被等待线程,可以被同一个锁上notify唤醒,不可以对不同锁中的线程进行唤醒。也就是说,等待和唤醒必须是同一个锁。
    3、而锁可以是任意对象,所以可以被任意对象调用的方法定义Object类中。
[java]  view plain copy
  1. /* 
  2. 线程间通讯: 
  3. 其实就是多个线程在操作同一个资源, 
  4. 但是操作的动作不同。 
  5. */  
  6. import java.lang.*;  
  7. class Res{  
  8.     String name;  
  9.     String sex;  
  10.     boolean flag = false;  
  11. }  
  12. class Input implements Runnable{  
  13.     private Res r;  
  14.     Input(Res r){  
  15.         this.r = r;  
  16.     }  
  17.     public void run(){  
  18.         int x = 0;  
  19.         while(true){  
  20.             synchronized(r){  
  21.                 if(r.flag){  
  22.                     try{ r.wait();}catch(Exception e){}  
  23.                 }  
  24.                 if(x==0){  
  25.                     r.name = "mike";  
  26.                     r.sex = "man";  
  27.                 }else{  
  28.                     r.name = "丽丽";  
  29.                     r.sex = "女女女女女";  
  30.                 }  
  31.                 x = (x+1)%2;  
  32.                 r.flag = true;  
  33.                 r.notify();  
  34.             }  
  35.         }  
  36.     }  
  37. }  
  38. class Output implements Runnable{  
  39.     private Res r;  
  40.     Output(Res r){  
  41.         this.r = r;  
  42.     }  
  43.     public void run(){  
  44.         while(true){  
  45.             synchronized(r){  
  46.                 if(!r.flag){  
  47.                     try{ r.wait();}catch(Exception e){}  
  48.                 }  
  49.                 System.out.println(r.name+"    "+r.sex);  
  50.                 r.flag = false;  
  51.                 r.notify();  
  52.             }  
  53.         }  
  54.     }  
  55. }  
  56. public class Demo{  
  57.     public static void main(String args[]){  
  58.         Res r = new Res();  
  59.         Input in = new Input(r);  
  60.         Output out = new Output(r);  
  61.         Thread t1 = new Thread(in);  
  62.         Thread t2 = new Thread(out);  
  63.         t1.start();  
  64.         t2.start();  
  65.     }  
  66. }  


四、线程间通信-代码优化
[java]  view plain copy
  1. class Res{  
  2.     private String name;  
  3.     private String sex;  
  4.     private boolean flag = false;  
  5.     public synchronized void set(String name,String sex){  
  6.         if(this.flag){  
  7.             trythis.wait();}catch(Exception e){}  
  8.         }  
  9.         this.name = name;  
  10.         this.sex = sex;  
  11.         this.flag = true;  
  12.         this.notify();  
  13.     }  
  14.     public synchronized void out(){  
  15.         if(!this.flag){  
  16.             trythis.wait();}catch(Exception e){}  
  17.         }  
  18.         System.out.println(this.name+"    "+this.sex);  
  19.         this.flag = false;  
  20.         this.notify();  
  21.     }  
  22. }  
  23. class Input implements Runnable{  
  24.     private Res r;  
  25.     Input(Res r){  
  26.         this.r = r;  
  27.     }  
  28.     public void run(){  
  29.         int x = 0;  
  30.         while(true){  
  31.             if(x==0){  
  32.                 r.set("mike","man");  
  33.             }else{  
  34.                 r.set("丽丽","女女女女女");  
  35.             }  
  36.             x = (x+1)%2;  
  37.         }  
  38.     }  
  39. }  
  40. class Output implements Runnable{  
  41.     private Res r;  
  42.     Output(Res r){  
  43.         this.r = r;  
  44.     }  
  45.     public void run(){  
  46.         while(true){  
  47.             r.out();  
  48.         }  
  49.     }  
  50. }  
  51. public class Demo{  
  52.     public static void main(String args[]){  
  53.         Res r = new Res();  
  54.         new Thread(new Input(r)).start();  
  55.         new Thread(new Output(r)).start();  
  56.     }  
  57. }  


五、线程间通信-生产者消费者
[java]  view plain copy
  1. class Demo{  
  2.     public static void main(String args[]){  
  3.         Resource r = new Resource();  
  4.         Producer pro = new Producer(r);  
  5.         Consumer con = new Consumer(r);  
  6.         Thread t1 = new Thread(pro);  
  7.         Thread t3 = new Thread(pro);  
  8.         Thread t2 = new Thread(con);  
  9.         Thread t4 = new Thread(con);  
  10.         t1.start();  
  11.         t2.start();  
  12.         t3.start();  
  13.         t4.start();  
  14.     }  
  15. }  
  16. class Resource{  
  17.     private String name;  
  18.     private int count = 1;  
  19.     private boolean flag = false;  
  20.       
  21.     public synchronized void set(String name){  
  22.         while(flag){  
  23.             try{  
  24.                 this.wait();  
  25.             }catch(Exception e){  
  26.                   
  27.             }  
  28.         }  
  29.         this.name = name+"--"+count++;  
  30.         System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);  
  31.         flag = true;  
  32.         this.notifyAll();  
  33.     }  
  34.     public synchronized void out(){  
  35.         while(!flag){  
  36.             try{  
  37.                 this.wait();  
  38.             }catch(Exception e){  
  39.                   
  40.             }  
  41.         }  
  42.         System.out.println(Thread.currentThread().getName()+"...消费者..........."+this.name);  
  43.         flag = false;  
  44.         this.notifyAll();  
  45.     }  
  46. }   
  47. class Producer implements Runnable{  
  48.     private Resource res;  
  49.     Producer(Resource res){  
  50.         this.res = res;  
  51.     }  
  52.     public void run(){  
  53.         while(true){  
  54.             res.set("+商品+");  
  55.         }  
  56.     }  
  57. }  
  58. class Consumer implements Runnable{  
  59.     private Resource res;  
  60.     Consumer(Resource res){  
  61.         this.res = res;  
  62.     }  
  63.     public void run(){  
  64.         while(true){  
  65.             res.out();  
  66.         }  
  67.     }  
  68. }  


六、线程间通信-生产者消费者JDK5.0升级版
    1、jdk1.5中,提供了,许多县城升级解决方案,将同步 synchrozed 替换成 显示 Lock 操作
    将 object 中的 wait ,notify,notifyAll,替换成了condition 对象。
    该对象可以 Lock锁,进行获取
    2、该实例中,实现了,本方置换型对方的操作。
[java]  view plain copy
  1. import java.util.concurrent.locks.*;  
  2. class Demo{  
  3.     public static void main(String args[]){  
  4.         Resource r = new Resource();  
  5.         Producer pro = new Producer(r);  
  6.         Consumer con = new Consumer(r);  
  7.         Thread t1 = new Thread(pro);  
  8.         Thread t3 = new Thread(pro);  
  9.         Thread t2 = new Thread(con);  
  10.         Thread t4 = new Thread(con);  
  11.         t1.start();  
  12.         t2.start();  
  13.         t3.start();  
  14.         t4.start();  
  15.     }  
  16. }  
  17. class Resource{  
  18.     private String name;  
  19.     private int count = 1;  
  20.     private boolean flag = false;  
  21.     private Lock lock = new ReentrantLock();  
  22.     private Condition condition_pro = lock.newCondition();  
  23.     private Condition condition_con = lock.newCondition();  
  24.     public void set(String name) throws InterruptedException{  
  25.         lock.lock();  
  26.         try{  
  27.             while(flag){  
  28.                 condition_pro.await();  
  29.             }  
  30.             this.name = name+"--"+count++;  
  31.             System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);  
  32.             flag = true;  
  33.             condition_con.signal();  
  34.         }finally{  
  35.             lock.unlock();  
  36.         }  
  37.     }  
  38.     public void out() throws InterruptedException{  
  39.         lock.lock();  
  40.         try{  
  41.             while(!flag){  
  42.                 condition_con.await();  
  43.             }  
  44.             System.out.println(Thread.currentThread().getName()+"...消费者..........."+this.name);  
  45.             flag = false;  
  46.             condition_pro.signal();  
  47.         }finally{  
  48.             lock.unlock();  
  49.         }  
  50.     }  
  51. }   
  52. class Producer implements Runnable{  
  53.     private Resource res;  
  54.     Producer(Resource res){  
  55.         this.res = res;  
  56.     }  
  57.     public void run(){  
  58.         while(true){  
  59.             try{  
  60.                 res.set("+商品+");  
  61.             }catch(InterruptedException e){  
  62.                   
  63.             }      
  64.         }  
  65.     }  
  66. }  
  67. class Consumer implements Runnable{  
  68.     private Resource res;  
  69.     Consumer(Resource res){  
  70.         this.res = res;  
  71.     }  
  72.     public void run(){  
  73.         while(true){  
  74.             try{  
  75.                 res.out();  
  76.             }catch(InterruptedException e){  
  77.                   
  78.             }  
  79.         }  
  80.     }  
  81. }  


七、停止线程
    stop方法已经过时。
    如何停止线程?
    只有一种,run()方法结束
    开启多线程运行,运行代码通常是循环结构。
    只要控制住循环,就可以让run方法结束,也就是线程结束
    
    当线程处于冻结状态,就不会读取到标记,那么线程就不会结束
    当没有指定的方式让冻结的线程恢复到运行状态时,这时需要对冻结进行清除。
    强制让线程恢复到运行状态中来,这样就可以操作标记让线程结束
    Thread类提供该方法,  interrupt();
[java]  view plain copy
  1. class Demo{  
  2.     public static void main(String args[]){  
  3.         StopThread st = new StopThread();  
  4.         Thread t1 = new Thread(st);  
  5.         Thread t2 = new Thread(st);  
  6.         t1.start();  
  7.         t2.start();  
  8.         int num = 0;  
  9.         while(true){  
  10.             if(num++ == 60){  
  11.                 st.changeFlag();  
  12.                 t1.interrupt();  
  13.                 t2.interrupt();  
  14.                 break;  
  15.             }  
  16.             System.out.println(Thread.currentThread().getName()+num);  
  17.         }  
  18.     }  
  19. }  
  20. class StopThread implements Runnable{  
  21.     private boolean flag = true;  
  22.     public void run(){  
  23.         while(flag){  
  24.             System.out.println(Thread.currentThread().getName()+"....run");  
  25.         }  
  26.     }  
  27.     public void changeFlag(){  
  28.         flag = false;  
  29.     }  
  30. }  


八、守护线程
    对象.setDemo(true)  如果主线程结束,则这个线程自动结束
九、Join方法
    抢夺主线程行权,注意,只抢夺主线程
    临时加入线程
    当a线程执行到了b线程的 .join() 方法时,a就会等待,等b线程都执行完,a才会执行
[java]  view plain copy
  1. class Demo{  
  2.     public static void main(String args[]) throws Exception{  
  3.         StopThread st = new StopThread();  
  4.         Thread t1 = new Thread(st);  
  5.         Thread t2 = new Thread(st);  
  6.         t1.start();  
  7.         t1.join();  
  8.         t2.start();  
  9.         t2.join();  
  10.         for(int x=0;x<70;x++){  
  11.             System.out.println(Thread.currentThread().getName()+"    "+x);  
  12.         }  
  13.         System.out.println("over");  
  14.     }  
  15. }  
  16. class StopThread implements Runnable{  
  17.     public void run(){  
  18.         for(int x=0;x<70;x++){  
  19.             System.out.println(Thread.currentThread().getName()+"    "+x);  
  20.         }  
  21.     }  
  22. }  


10、Byield方法  礼让

    setPriority  设置优先级

你可能感兴趣的:(Java基础---第十二天 多线程)