正確運用synchronized和二次判斷 實現多線程安全,作出高效二符合預期的程序,特別是多個線程跑一個對象的時候,以下圖所示: java
測試代碼以下: 特別注意*if(shutdownRequested){ **部分不一樣的寫法。安全
否則就會輸出與邏輯不符的現象: 如:多線程
runner----false----我沒有關閉。。。測試
runner----true----我沒有關閉。。。this
runner----true----我關閉了=====>>>線程
package com.xue.gang.volatiler;code
import java.util.concurrent.CountDownLatch;對象
import java.util.concurrent.ExecutorService;圖片
import java.util.concurrent.Executors;it
public class VolatileRunner{
public static void main(String args[]) throws InterruptedException { int size=1000; CountDownLatch countDownLatch = new CountDownLatch(size); TomRunner tomRunner = new TomRunner(false,countDownLatch,"runner"); ExecutorService executorService = Executors.newCachedThreadPool(); for(int i=1;i<=size;i++){ executorService.execute(new Thread2RunTomRunner(countDownLatch,tomRunner,i+"_號")); } countDownLatch.await(); executorService.shutdown(); //new Thread(volatileRunner).start(); } static class Thread2RunTomRunner implements Runnable{ private CountDownLatch countDownLatch; private TomRunner tomRunner; private String name; public Thread2RunTomRunner(CountDownLatch countDownLatch, TomRunner tomRunner, String name) { super(); this.countDownLatch = countDownLatch; this.tomRunner = tomRunner; this.name = name; } public void run() { System.out.println(this.name+":running..."); this.tomRunner.doWork(); System.out.println(this.name+":結束..."); this.countDownLatch.countDown(); } } static class TomRunner{ volatile boolean shutdownRequested = false; //boolean shutdownRequested = false; String name; public TomRunner(boolean shutdownRequested, CountDownLatch countDownLatch, String name) { super(); this.shutdownRequested = shutdownRequested; this.name = name; } public void shutdown() { this.shutdownRequested = true; } public void doWork() { while (true) { /** *多個線程的代碼去執行: System.out.println(this.name + "----" + this.shutdownRequested +"----" +"我沒有關閉。。。"); * */ /*if(shutdownRequested){ System.out.println(this.name + "----" + this.shutdownRequested +"----" +"我關閉了=====>>>"); break; }else{ System.out.println(this.name + "----" + this.shutdownRequested +"----" +"我沒有關閉。。。"); shutdown(); }*/ /** * 若是沒有二次判斷,也會出現比較髒數據. * */ /* if(shutdownRequested){ System.out.println(this.name + "----" + this.shutdownRequested +"----" +"我關閉了=====>>>"); break; } synchronized (this) { System.out.println(this.name + "----" + this.shutdownRequested +"----" +"我沒有關閉。。。"); shutdown(); }*/ /** * 加上二次判斷,可以正確 * */ if(shutdownRequested){ System.out.println(this.name + "----" + this.shutdownRequested +"----" +"我關閉了=====>>>"); break; } synchronized (this) { if(!shutdownRequested){ System.out.println(this.name + "----" + this.shutdownRequested +"----" +"我沒有關閉。。。"); shutdown(); } } } } }
}