join、volatile、newSingleThreadLatch 實現執行緒順序執行

litblank發表於2018-03-09

1、join

阻塞當前執行緒、執行呼叫執行緒。

public static void main(String[] args) throws InterruptedException {
		Thread thread_1;
		Thread thread_2;
		Thread thread_3;
		
		thread_1=new Thread(()->{
			System.out.println(Thread.currentThread().getName()+":1"); 
		});
		
		thread_2=new Thread(()->{
			try {
				thread_1.join();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+":2"); 
		});
		
		thread_3=new Thread(()->{
			try {
				thread_2.join();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+":3");
		});
		
		System.out.println("執行緒啟動");
		Thread.sleep(500);
		thread_1.start();
		thread_2.start();
		thread_3.start();
		
	}
複製程式碼

2、volatile

性質:

  • 可見性
  • 原子性
  • 禁止指令重排序。

保證執行緒同步,volatile本身執行緒不安全,是因為在寫入主記憶體,其他執行緒可能讀取主記憶體 ,導致讀出有誤。結合volatile適合的使用場景,可以使用。

  • 對變數的寫操作不依賴於當前值。(大白話:修改後的變數值與當前值無關)
  • 該變數沒有包含在具有其他變數的不變式中。(大白話:儘量volatile變數不影響其他變數)
static volatile int flag=0;
	
	public static void main(String[] args) throws InterruptedException {
		
		Thread thread_1=new Thread(()->{
			while(true){
				if(flag==1){
					System.out.println(Thread.currentThread().getName()+":1");
					flag++;
					break;
				}
			}
		});
		
		Thread thread_2=new Thread(()->{
			while(true){
				if(flag==2){
					System.out.println(Thread.currentThread().getName()+":2");
					flag++;
					break;
				}
			}
		});
		
		Thread thread_3=new Thread(()->{
			while(true){
				if(flag==3){
					System.out.println(Thread.currentThread().getName()+":3");
					flag++;
					break;
				}
			}
		});
		
		thread_1.start();
		thread_2.start();
		thread_3.start();
		System.out.println("執行緒啟動");
		Thread.sleep(1000);
		flag=1;
		
		
	}
複製程式碼

3、newSingleThreadLatch

執行緒池,按順序執行,內部有ThreadPoolExecutor實現一個主執行緒的執行緒池

  public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }
複製程式碼
public static void main(String[] args) throws InterruptedException {
		Thread thread_1;
		Thread thread_2;
		Thread thread_3;
		
		thread_1=new Thread(()->{
			System.out.println(Thread.currentThread().getName()+":1"); 
		});
		
		thread_2=new Thread(()->{
			System.out.println(Thread.currentThread().getName()+":2"); 
		});
		
		thread_3=new Thread(()->{
			System.out.println(Thread.currentThread().getName()+":3");
		});
		
		ExecutorService exe=Executors.newSingleThreadExecutor();
		exe.submit(thread_1);
		exe.submit(thread_2);
		exe.submit(thread_3);
		exe.shutdown();
	}
複製程式碼

其他

想使用同步執行緒,CountDownLatch執行緒實現,但好像只有當countDown()到0才能啟動。不對的地方,也希望大家指正。

相關文章