正確運用synchronized和二次判斷 實現多線程安全

正確運用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();
				}
			} 			
		}
	}
}

}

相關文章
相關標籤/搜索