JAVA 11(多線程)

來源:互聯網
上載者:User

標籤:

線程間通訊,其實就是多個線程在操作同一個資源,但操作動作不同。  同步代碼塊用了同一個鎖。 public class Test{ public static void main(String args []) {  Res r = new Res();  Input in = new Input(r);  Output out = new Output(r);  Thread t1 = new Thread(in);  Thread t2 =new Thread(out);  t1.start();  t2.start(); }} class Res{ String name; String sex;} class Input implements Runnable{ Res r ;  Input(Res r) {  this.r = r; } public void run() {  boolean b = true;  while(true)  {   synchronized(r)   {   if(b)   {    r.name="mike";    r.sex="man";    b=false;   }   else   {    r.name="麗麗";    r.sex="女女女女";    b=true;   }   }  } }} class Output implements Runnable{ Res r; Output(Res r) {  this.r=r; } public void run() {  while(true)  {   synchronized(r)   {   System.out.println(r.name+"....."+r.sex);   }  } }} 改代碼 會列印重複的 同一個人,利用線程直接的通訊修改,在Res中給一個標記。  等待喚醒機制    非靜態同步函數用的鎖時this。靜態同步函數用的鎖時 類名.class。同步代碼塊用的鎖任意。自己設定的  wait()   :格式 try{} catch() {}notify() notifyAll() 三個方法都繼承於Object類,後兩個方法必須有對象的監視器才可以使用(也就是同步中的鎖,必須在同步中才可以使用) 都使用在同步中,因為要對持有監視器(鎖)的線程操作,所以要使用在同步中,因為只有在同步中,才有鎖。 為什麼操作線程的方法要定義在Object中呢,因為這些方法在操作同步中的線程時,都必須要標示他們所操作線程持有的鎖,只有同一個鎖上的被等待線程可以被同一個鎖上notify()喚醒,不可以對不同所中的線程進行喚醒也就是說,等待和喚醒必須是同一個鎖,而鎖可以是任意對象,所以可以被任意對象調用的方法定義在Obj類中。  public class Test{ public static void main(String args []) {  Res r = new Res();  Input in = new Input(r);  Output out = new Output(r);  Thread t1 = new Thread(in);  Thread t2 =new Thread(out);  t1.start();  t2.start(); }} class Res{ String name; String sex; boolean flag = false;} class Input implements Runnable{ Res r ;  Input(Res r) {  this.r = r; } public void run() {  boolean b = true;  while(true)  {   synchronized(r)   {    if(r.flag)     try    {     r.wait();    }   catch(Exception e)   {      }   if(b)   {    r.name="mike";    r.sex="man";    b=false;   }   else   {    r.name="麗麗";    r.sex="女女女女";    b=true;   }   r.flag=true;   r.notify();   }  } }} class Output implements Runnable{ Res r; Output(Res r) {  this.r=r; } public void run() {  while(true)  {   synchronized(r)   {    if(!r.flag)     try     {      r.wait();     }    catch(Exception e)    {         }        System.out.println(r.name+"....."+r.sex);   r.flag=false;   r.notify();   }  } }}  繼續舉例:多個線程負責生產,多個線程負責消費。注意notifyAll 和while(flag) 對於多個生產者和消費者。為什麼要定義while判斷標記?讓被喚醒的線程再一次判斷標記。 為什麼要定義notifyAll因為需要喚醒對方線程。因為只用notify的話,容易出只喚醒本方線程的情況,導致程式中所有線程都等待。   public class Test{ 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);  Thread t3 = new Thread(pro);  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(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; public void run() {  while(true)  {   res.set("+商品+");  } } Producer(Resource res) {  this.res=res; }} class Consumer implements Runnable{ private Resource res; public void run() {  while(true)  {   res.out();  } } Consumer(Resource res) {  this.res=res; } }   jdk5升級之後   java.util.concurrent.locks 介面 jdk1.5中提供了多線程的升級解決方案,將同步的Synchronized 替換成Lock操作,將Object中的wait,notify,nofityAll替換成立Condition對象,該對象可以Lock鎖,進行擷取。一個鎖可以對應多個Condition。 JDK1.5 中提供了多線程升級解決方案。將同步Synchronized替換成現實Lock操作。將Object中的wait,notify notifyAll,替換了Condition對象。該對象可以Lock鎖 進行擷取。該樣本中,實現了本方只喚醒對方操作。 Lock:替代了Synchronized lock unlock new Condition() Condition:替代了Object wait notify notifyAll await(); signal(); signalAll();  在該實力中,實現了本方只喚醒對方的操作。更改之後的代碼: import java.util.concurrent.locks.*; class Test{ 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();  }} /*JDK1.5 中提供了多線程升級解決方案。將同步Synchronized替換成現實Lock操作。將Object中的wait,notify notifyAll,替換了Condition對象。該對象可以Lock鎖 進行擷取。該樣本中,實現了本方只喚醒對方操作。 Lock:替代了Synchronized lock unlock newCondition() Condition:替代了Object wait notify notifyAll await(); signal(); signalAll();*/class Resource{ private String name; private int count = 1; private boolean flag = false;   //  t1    t2 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)    condition_pro.await();//t1,t2   this.name = name+"--"+count++;    System.out.println(Thread.currentThread().getName()+"...生產者.."+this.name);   flag = true;   condition_con.signal();  }  finally  {   lock.unlock();//釋放鎖的動作一定要執行。  } }   //  t3   t4   public  void out()throws InterruptedException {  lock.lock();  try  {   while(!flag)    condition_con.await();   System.out.println(Thread.currentThread().getName()+"...消費者........."+this.name);   flag = false;   condition_pro.signal();  }  finally  {   lock.unlock();  }  }} class Producer implements Runnable{ private Resource res;  Producer(Resource res) {  this.res = res; } public void run() {  while(true)  {   try   {    res.set("+商品+");   }   catch (InterruptedException e)   {   }     } }} class Consumer implements Runnable{ private Resource res;  Consumer(Resource res) {  this.res = res; } public void run() {  while(true)  {   try   {    res.out();   }   catch (InterruptedException e)   {   }  } }}     停止線程  停止線程的原理只有一種方法,就是run()方法結束 線程.interrupt  //強制喚醒 stop方法已經過時。 如何停止線程?只有一種,run方法結束。開啟多線程運行,運行代碼通常是迴圈結構。 只要控制住迴圈,就可以讓run方法結束,也就是線程結束。  特殊情況:當線程處於了凍結狀態。就不會讀取到標記。那麼線程就不會結束。 當沒有指定的方式讓凍結的線程恢複到運行狀態是,這時需要對凍結進行清除。強制讓線程恢複到運行狀態中來。這樣就可以操作標記讓線程結束。 Thread類提供該方法 interrupt();    設定為守護線程,當其他線程都結束後,並且只剩下守護線程,守護線程自動結束而且必須早start()之前設定守護線程   join方法 t1.join(); 搶奪cpu執行權,當t1執行結束的時候,主線程才解凍。 join:當A線程執行到了B線程的.join()方法時,A就會等待。等B線程都執行完,A才會執行。 join可以用來臨時加入線程執行。    線程的優先順序        自己寫的代碼:import java.util.concurrent.locks.*;import java.util.concurrent.locks.Lock.*; public class Test{ public static void main(String args[]) {  Resource r = new Resource();  Pro p = new Pro(r);  Cro c = new Cro(r);  Thread t1 = new Thread(p);  Thread t2 = new Thread(p);  Thread t3 = new Thread(c);  Thread t4 = new Thread(c);  t1.start();  t2.start();  t3.start();  t4.start();   }} class Resource{  private boolean flag = false; private int count = 1;  private Lock lock = new ReentrantLock(); private Condition con_pro = lock.newCondition(); private Condition con_con = lock.newCondition();  public void set() {    lock.lock();       try {     while(flag)     con_pro.await();     count++;     System.out.println(Thread.currentThread().getName()+"生產了第"+count+"張票");     flag=true;     con_con.signal();    } catch (InterruptedException e) {         }    finally    {     lock.unlock();    }       }   public void hua() {    lock.lock();       try {     while(!flag)     con_con.await();     System.out.println(Thread.currentThread().getName()+"消費了第"+count+"張票***");     flag=false;     con_pro.signal();    } catch (InterruptedException e) {         }    finally    {     lock.unlock();    }    }  } class Pro implements Runnable{ Resource r; Pro(Resource r) {  this.r=r; }  public void run() {  while(true)   r.set(); }} class Cro implements Runnable{ Resource r; Cro(Resource r) {  this.r=r; }  public void run() {  while(true)   r.hua(); }}

JAVA 11(多線程)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.