程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java Thread多線程詳解及用法解析

Java Thread多線程詳解及用法解析

編輯:關於JAVA

Java Thread多線程詳解及用法解析。本站提示廣大學習愛好者:(Java Thread多線程詳解及用法解析)文章只能為提供參考,不一定能成為您想要的結果。以下是Java Thread多線程詳解及用法解析正文


最周全的java多線程用法解析,假如你對Java的多線程機制並沒有深刻的研討,那末本文可以贊助你更透辟地輿解Java多線程的道理和應用辦法。

1.創立線程

在Java中創立線程有兩種辦法:應用Thread類和應用Runnable接口。在應用Runnable接口時須要樹立一個Thread實例。是以,不管是經由過程Thread類照樣Runnable接口樹立線程,都必需樹立Thread類或它的子類的實例。Thread結構函數:

  1. public Thread( );
  2. public Thread(Runnable target);
  3. public Thread(String name);
  4. public Thread(Runnable target, String name);
  5. public Thread(ThreadGroup group, Runnable target);
  6. public Thread(ThreadGroup group, String name);
  7. public Thread(ThreadGroup group, Runnable target, String name);
  8. public Thread(ThreadGroup group, Runnable target, String name, long stackSize);
  9. 辦法一:繼續Thread類籠罩run辦法

    public class ThreadDemo1 {
      public static void main(String[] args){
       Demo d = new Demo();
       d.start();
       for(int i=0;i<60;i++){
        System.out.println(Thread.currentThread().getName()+i);
       }
    
      }
     }
     class Demo extends Thread{
      public void run(){
       for(int i=0;i<60;i++){
        System.out.println(Thread.currentThread().getName()+i);
       }
      }
     }
    
    

    辦法二:

    public class ThreadDemo2 {
     public static void main(String[] args){
      Demo2 d =new Demo2();
      Thread t = new Thread(d);
      t.start();
      for(int x=0;x<60;x++){
       System.out.println(Thread.currentThread().getName()+x);
      }
     }
    }
    class Demo2 implements Runnable{
     public void run(){
      for(int x=0;x<60;x++){
       System.out.println(Thread.currentThread().getName()+x);
      }
     }
    }
    

    2.線程的性命周期

    與人有生老病逝世一樣,線程也異樣要閱歷開端(期待)、運轉、掛起和停滯四種分歧的狀況。這四種狀況都可以經由過程Thread類中的辦法停止掌握。上面給出了Thread類中和這四種狀況相干的辦法。

    // 開端線程
    publicvoid start( );
    publicvoid run( );
    // 掛起和叫醒線程
    publicvoid resume( );     // 不建議應用
    publicvoid suspend( );    // 不建議應用
    publicstaticvoid sleep(long millis);
    publicstaticvoid sleep(long millis, int nanos);
    // 終止線程
    publicvoid stop( );       // 不建議應用
    publicvoid interrupt( );
    // 獲得線程狀況
    publicboolean isAlive( );
    publicboolean isInterrupted( );
    publicstaticboolean interrupted( );
    // join辦法
    publicvoid join( ) throws InterruptedException;

    線程在樹立後其實不立時履行run辦法中的代碼,而是處於期待狀況。線程處於期待狀況時,可以經由過程Thread類的辦法來設置線程不各類屬性,如線程的優先級(setPriority)、線程名(setName)和線程的類型(setDaemon)等。

    當挪用start辦法後,線程開端履行run辦法中的代碼。線程進入運轉狀況。可以經由過程Thread類的isAlive辦法來斷定線程能否處於運轉狀況。當線程處於運轉狀況時,isAlive前往true,當isAlive前往false時,能夠線程處於期待狀況,也能夠處於停滯狀況。上面的代碼演示了線程的創立、運轉和停滯三個狀況之間的切換,並輸入了響應的isAlive前往值。

    一但線程開端履行run辦法,就會一向到這個run辦法履行完成這個線程才加入。但在線程履行的進程中,可以經由過程兩個辦法使線程臨時停滯履行。這兩個辦法是suspend和sleep。在應用suspend掛起線程後,可以經由過程resume辦法叫醒線程。而應用sleep使線程休眠後,只能在設定的時光後使線程處於停當狀況(在線程休眠停止後,線程紛歧定會立時履行,只是進入了停當狀況,期待著體系停止調劑)。

    在應用sleep辦法時有兩點須要留意:

    1. sleep辦法有兩個重載情勢,個中一個重載情勢不只可以設毫秒,並且還可以設納秒(1,000,000納秒等於1毫秒)。但年夜多半操作體系平台上的Java虛擬機都沒法准確到納秒,是以,假如對sleep設置了納秒,Java虛擬機將取最接近這個值的毫秒。

    2. 在應用sleep辦法時必需應用throws或try{…}catch{…}。由於run辦法沒法應用throws,所以只能應用try{…}catch{…}。當在線程休眠的進程中,應用interrupt辦法中止線程時sleep會拋出一個InterruptedException異常。sleep辦法的界說以下:

    publicstaticvoid sleep(long millis) throws InterruptedException
    publicstaticvoid sleep(long millis, int nanos) throws InterruptedException

    有三種辦法可使終止線程。

    1.  應用加入標記,使線程正常加入,也就是當run辦法完成後線程終止。

    2.  應用stop辦法強行終止線程(這個辦法不推舉應用,由於stop和suspend、resume一樣,也能夠產生弗成預感的成果)。

    3.  應用interrupt辦法中止線程。

    1. 應用加入標記終止線程

    當run辦法履行完後,線程就會加入。但有時run辦法是永久不會停止的。如在辦事端法式中應用線程停止監聽客戶端要求,或是其他的須要輪回處置的義務。在這類情形下,普通是將這些義務放在一個輪回中,如while輪回。假如想讓輪回永久運轉下去,可使用while(true){…}來處置。但要想使while輪回在某一特定前提下加入,最直接的辦法就是設一個boolean類型的標記,並經由過程設置這個標記為true或false來掌握while輪回能否加入。上面給出了一個應用加入標記終止線程的例子。

    join辦法的功效就是使異步履行的線程釀成同步履行。也就是說,當挪用線程實例的start辦法後,這個辦法會立刻前往,假如在挪用start辦法後後須要應用一個由這個線程盤算獲得的值,就必需應用join辦法。假如不應用join辦法,就不克不及包管當履行到start辦法前面的某條語句時,這個線程必定會履行完。而應用join辦法後,直到這個線程加入,法式才會往下履行。上面的代碼演示了join的用法。

    3.多線程平安成績

    成績緣由:當多條語句在操作統一個線程同享數據時,一個線程對多條語句只履行了一部門,還沒履行完,另外一個線程介入出去履行,招致同享數據的毛病。

    處理方法:對多條操作同享數據的語句,只能讓一個線程都履行完,在履行進程中,其他線程不履行。

    同步代碼塊:

    public class ThreadDemo3 {
     public static void main(String[] args){
      Ticket t =new Ticket();
      Thread t1 = new Thread(t,"窗口一");
      Thread t2 = new Thread(t,"窗口二");
      Thread t3 = new Thread(t,"窗口三");
      Thread t4 = new Thread(t,"窗口四");
      t1.start();
      t2.start();
      t3.start();
      t4.start();
     }
    }
    class Ticket implements Runnable{
     private int ticket =400;
     public void run(){
      while(true){
       synchronized (new Object()) {
        try {
         Thread.sleep(1);
        } catch (InterruptedException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
        }
        if(ticket<=0)
         break;
        System.out.println(Thread.currentThread().getName()+"---賣出"+ticket--);
       }
      }
     }
    }
    

    同步函數

    public class ThreadDemo3 {
     public static void main(String[] args){
      Ticket t =new Ticket();
      Thread t1 = new Thread(t,"窗口一");
      Thread t2 = new Thread(t,"窗口二");
      Thread t3 = new Thread(t,"窗口三");
      Thread t4 = new Thread(t,"窗口四");
      t1.start();
      t2.start();
      t3.start();
      t4.start();
     }
    }
    class Ticket implements Runnable{
     private int ticket = 4000;
     public synchronized void saleTicket(){
      if(ticket>0)
       System.out.println(Thread.currentThread().getName()+"賣出了"+ticket--);
    
     }
     public void run(){
      while(true){
       saleTicket();
      }
     }
    }
    
    

    同步函數鎖是this 靜態同步函數鎖是class

    線程間的通訊

    public class ThreadDemo3 {
     public static void main(String[] args){
      class Person{
       public String name;
       private String gender;
       public void set(String name,String gender){
        this.name =name;
        this.gender =gender;
       }
       public void get(){
        System.out.println(this.name+"...."+this.gender);
       }
      }
      final Person p =new Person();
      new Thread(new Runnable(){
       public void run(){
        int x=0;
        while(true){
         if(x==0){
          p.set("張三", "男");
         }else{
          p.set("lili", "nv");
         }
         x=(x+1)%2;
        }
       }
      }).start();
      new Thread(new Runnable(){
       public void run(){
        while(true){
         p.get();
        }
       }
      }).start();
     }
    }
    /*
    張三....男
    張三....男
    lili....nv
    lili....男
    張三....nv
    lili....男
    */
    

    修正下面代碼

    public class ThreadDemo3 {
      public static void main(String[] args){
       class Person{
        public String name;
        private String gender;
        public void set(String name,String gender){
         this.name =name;
         this.gender =gender;
        }
        public void get(){
         System.out.println(this.name+"...."+this.gender);
        }
       }
       final Person p =new Person();
       new Thread(new Runnable(){
        public void run(){
         int x=0;
         while(true){
          synchronized (p) {
           if(x==0){
            p.set("張三", "男");
           }else{
            p.set("lili", "nv");
           }
           x=(x+1)%2; 
          }
    
         }
        }
       }).start();
       new Thread(new Runnable(){
        public void run(){
         while(true){
          synchronized (p) {
           p.get();
          }
         }
        }
       }).start();
      }
    
     }
     /*
     lili....nv
     lili....nv
     lili....nv
     lili....nv
     lili....nv
     lili....nv
     張三....男
     張三....男
     張三....男
     張三....男
     */
    
    

    期待叫醒機制

    /*
     *線程期待叫醒機制
     *期待和叫醒必需是統一把鎖 
     */
    public class ThreadDemo3 {
     private static boolean flags =false;
     public static void main(String[] args){
      class Person{
       public String name;
       private String gender;
       public void set(String name,String gender){
        this.name =name;
        this.gender =gender;
       }
       public void get(){
        System.out.println(this.name+"...."+this.gender);
       }
      }
      final Person p =new Person();
      new Thread(new Runnable(){
       public void run(){
        int x=0;
        while(true){
         synchronized (p) {
          if(flags)
           try {
            p.wait();
           } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
           };
          if(x==0){
           p.set("張三", "男");
          }else{
           p.set("lili", "nv");
          }
          x=(x+1)%2;
          flags =true;
          p.notifyAll();
         }
        }
       }
      }).start();
      new Thread(new Runnable(){
       public void run(){
        while(true){
         synchronized (p) {
          if(!flags)
           try {
            p.wait();
           } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
           };
          p.get();
          flags =false;
          p.notifyAll();
          }
        }
       }
      }).start();
     }
    }
    

    臨盆花費機制一

    public class ThreadDemo4 {
     private static boolean flags =false;
     public static void main(String[] args){
      class Goods{
       private String name;
       private int num;
       public synchronized void produce(String name){
        if(flags)
         try {
          wait();
         } catch (InterruptedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
         }
        this.name =name+"編號:"+num++;
        System.out.println("臨盆了...."+this.name);
        flags =true;
        notifyAll();
       }
       public synchronized void consume(){
        if(!flags)
         try {
          wait();
         } catch (InterruptedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
         }
        System.out.println("花費了******"+name);
        flags =false;
        notifyAll();
       }
    
      }
      final Goods g =new Goods();
      new Thread(new Runnable(){
       public void run(){
        while(true){
         g.produce("商品");
        }
       }
      }).start();
      new Thread(new Runnable(){
       public void run(){
        while(true){
         g.consume();
        }
       }
      }).start();
     }
    }
    
    

    臨盆花費機制2

    public class ThreadDemo4 {
     private static boolean flags =false;
     public static void main(String[] args){
      class Goods{
       private String name;
       private int num;
       public synchronized void produce(String name){
        while(flags)
         try {
          wait();
         } catch (InterruptedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
         }
        this.name =name+"編號:"+num++;
        System.out.println(Thread.currentThread().getName()+"臨盆了...."+this.name);
        flags =true;
        notifyAll();
       }
       public synchronized void consume(){
        while(!flags)
         try {
          wait();
         } catch (InterruptedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
         }
        System.out.println(Thread.currentThread().getName()+"花費了******"+name);
        flags =false;
        notifyAll();
       }
    
      }
      final Goods g =new Goods();
      new Thread(new Runnable(){
       public void run(){
        while(true){
         g.produce("商品");
        }
       }
      },"臨盆者一號").start();
      new Thread(new Runnable(){
       public void run(){
        while(true){
         g.produce("商品");
        }
       }
      },"臨盆者二號").start();
      new Thread(new Runnable(){
       public void run(){
        while(true){
         g.consume();
        }
       }
      },"花費者一號").start();
      new Thread(new Runnable(){
       public void run(){
        while(true){
         g.consume();
        }
       }
      },"花費者二號").start();
     }
    }
    /*
    花費者二號花費了******商品編號:48049
    臨盆者一號臨盆了....商品編號:48050
    花費者一號花費了******商品編號:48050
    臨盆者一號臨盆了....商品編號:48051
    花費者二號花費了******商品編號:48051
    臨盆者二號臨盆了....商品編號:48052
    花費者二號花費了******商品編號:48052
    臨盆者一號臨盆了....商品編號:48053
    花費者一號花費了******商品編號:48053
    臨盆者一號臨盆了....商品編號:48054
    花費者二號花費了******商品編號:48054
    臨盆者二號臨盆了....商品編號:48055
    花費者二號花費了******商品編號:48055
    */
    
    

    以上就是對Java 多線程的材料整頓,後續持續彌補相干常識,感謝年夜家對本站的支撐!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved