JAVA多線程順序執行(使用join,lock,condition,信號量)原理和java源代碼

java多線程順序執行問題

 

使用join

假設我要讓3個線程按照順序打印ABC,那麼可使用Join,若是要求多線程按順序循環打印,則不能用join了java

join關鍵字

join是Thread類的一個方法,啓動線程後直接調用。在不少狀況下,主線程生成並起動了子線程,若是子線程裏要進行大量的耗時的運算,主線程每每將於子線程以前結束,可是若是主線程處理完其餘的事務後,須要用到子線程的處理結果,也就是主線程須要等待子線程執行完成以後再結束,這個時候就要用到join()方法了。git

join()的做用是:「等待該線程終止」,這裏須要理解的就是該線程是指的主線程等待子線程的終止。也就是在子線程調用了join()方法後面的代碼,只有等到子線程結束了才能執行。github

具體代碼:多線程

package googleTest;  
  
public class ThreadTest {    
    public static void main(String[] args) throws InterruptedException {    
        Thread t1 = new Thread(new Runner("A"));    
        Thread t2 = new Thread(new Runner("B"));    
        Thread t3 = new Thread(new Runner("C"));    
        t1.start();    
        t1.join();    
        t2.start();    
        t2.join();    
        t3.start();    
        t3.join();    
        
    }    
        
}    
    
class Runner implements Runnable{   
    public String name;  
      
    Runner(String name)  
    {  
        this.name=name;  
    }  
    
    @Override    
    public void run() {    
        System.out.println(name+"");    
            
    }    
        
}   

 

使用lock和全局變量

</pre>lock時注意unlock就能夠啦</p><p class="p1"><pre name="code" class="java">import java.util.concurrent.locks.Lock;  
import java.util.concurrent.locks.ReentrantLock;  
   
public class ThreadTest3 {  
    private static Lock lock=new ReentrantLock();  
     private static int state = 0;  
      
    static class ThreadA extends Thread {  
         @Override  
         public void run() {  
                lock.lock();  
                 if (state % 3 == 0) {  
                     System.out.println("A");  
                     state++;  
                 }  
                 lock.unlock();  
         }  
     }  
       
     static class ThreadB extends Thread {  
         @Override  
         public void run() {  
                 lock.lock();  
                if (state % 3 == 1) {  
                     System.out.println("B");  
                    state++;  
                 }  
                 lock.unlock();  
             }  
              
         }  
       
     static class ThreadC extends Thread {  
         @Override  
         public void run() {  
                 lock.lock();  
                 if (state % 3 == 2) {  
                     System.out.println("C");  
                     state++;  
                }  
                 lock.unlock();  
         }  
     }  
       
     public static void main(String[] args) {  
         new ThreadA().start();  
         new ThreadB().start();  
         new ThreadC().start();  
     }  
       
 }  

 

使用condition

condition關鍵字

就拿生產者消費者模式來講,當倉庫滿了的時候,又再執行到 生產者 線程的時候,會把 該 生產者 線程進行阻塞,再喚起一個線程.併發

可是此時喚醒的是消費者線程仍是生產者線程,是未知的。若是再次喚醒的仍是生產者線程,那麼還須要把它進行阻塞,再喚起一個線程,再此循環,直到喚起的是消費者線程。這樣就可能存在 時間或者資源上的浪費,ide

因此說 有了Condition 這個東西。Condition 用 await() 代替了 Object 的 wait() 方法,用 signal() 方法代替 notify() 方法。注意:Condition 是被綁定到 Lock 中,要建立一個 Lock 的 Condition 必須用 newCondition() 方法。ui

import java.util.concurrent.locks.Condition;  
import java.util.concurrent.locks.Lock;  
import java.util.concurrent.locks.ReentrantLock;  
public class ThreadTest2 {  
     private static Lock lock = new ReentrantLock();  
     private static int count = 0;  
     private static Condition A = lock.newCondition();  
     private static Condition B = lock.newCondition();  
     private static Condition C = lock.newCondition();  
      
     static class ThreadA extends Thread {  
   
         @Override  
         public void run() {  
             lock.lock();  
             try {  
                 for (int i = 0; i < 10; i++) {  
                     while (count % 3 != 0)  
                         A.await(); // 會釋放lock鎖  
                        System.out.print("A");  
                     count++;  
                     B.signal(); // 喚醒相應線程  
                 }  
             } catch (InterruptedException e) {  
                 e.printStackTrace();  
            } finally {  
                 lock.unlock();  
             }  
         }  
           
     }  
       
     static class ThreadB extends Thread {  
   
         @Override  
        public void run() {  
             lock.lock();  
             try {  
                for (int i = 0; i < 10; i++) {  
                    while (count % 3 != 1)  
                         B.await();  
                     System.out.print("B");  
                     count++;  
                   C.signal();  
                 }  
             } catch (InterruptedException e) {  
                 e.printStackTrace();  
            } finally {  
                 lock.unlock();  
             }  
        }  
           
     }  
  
     static class ThreadC extends Thread {  
  
         @Override  
         public void run() {  
             lock.lock();  
             try {  
                 for (int i = 0; i < 10; i++) {  
                     while (count % 3 != 2)  
                         C.await();  
                     System.out.println("C");  
                     count++;  
                     A.signal();  
              }  
             } catch (InterruptedException e) {  
                e.printStackTrace();  
             } finally {  
                 lock.unlock();  
             }  
         }  
         
    }  
       
     public static void main(String[] args) throws InterruptedException {  
         new ThreadA().start();  
         new ThreadB().start();  
         ThreadC threadC = new ThreadC();  
         threadC.start();  
         threadC.join();  
         System.out.println(count);  
     }  
 }  

 

使用信號量

Semaphore關鍵字

 

Semaphore爲併發包中提供用於控制某資源同時能夠被幾個線程訪問的類。通常用於限制線程訪問的資源個數。也可用於線程間的信號傳遞。this

import java.util.concurrent.Semaphore;  
   
public class ThreadTest4 {  
     private static Semaphore A = new Semaphore(1);  
     private static Semaphore B = new Semaphore(1);  
     private static Semaphore C = new Semaphore(1);  
       
    static class ThreadA extends Thread {  
   
        @Override  
        public void run() {  
            try {  
                for (int i = 0; i < 10; i++) {  
                    A.acquire();  
                    System.out.print("A");  
                    B.release();  
                }  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
        }  
          
    }  
      
    static class ThreadB extends Thread {  
  
        @Override  
        public void run() {  
            try {  
                for (int i = 0; i < 10; i++) {  
                    B.acquire();  
                    System.out.print("B");  
                    C.release();  
                }  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
        }  
          
    }  
      
    static class ThreadC extends Thread {  
  
       @Override  
        public void run() {  
            try {  
                for (int i = 0; i < 10; i++) {  
                    C.acquire();  
                    System.out.println("C");  
                    A.release();  
                }  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
        }  
          
    }  
      
    public static void main(String[] args) throws InterruptedException {  
        B.acquire(); C.acquire(); // 開始只有A能夠獲取, BC都不能夠獲取, 保證了A最早執行  
        new ThreadA().start();  
        new ThreadB().start();  
        new ThreadC().start();  
    }  
}  
相關文章
相關標籤/搜索