【Effective Java】11、同步訪問共用的可變資料,effectivejava
這段時間看的部分感覺沒啥需要記錄下來的,個人也沒什麼想法,不過以後還是要多記,多寫
package cn.xf.cp.ch02.item66;import java.util.concurrent.TimeUnit;import org.junit.Test;public class StopThread{ /** * 停止線程變數 */ private static boolean stopRequested; //吧對變數的讀和寫方法都進行同步 private static synchronized void requestStop() { stopRequested = true; } private static synchronized boolean stopRequested() { return stopRequested; } /** * 停止線程變數,這個使用關鍵字volatile使每個線程都是擷取到最新的值 */ private static volatile boolean stopRequested2; @Test public void test() { Thread backgroundThread = new Thread(new Runnable() { @Override public void run() { int i = 0; while(!stopRequested()) { ++i; } } }); //啟動線程 backgroundThread.start(); //休眠1秒 try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } requestStop(); } @Test public void test2() { Thread backgroundThread = new Thread(new Runnable() { @Override public void run() { int i = 0; System.out.println("這裡使用最新的stopRequested2值"); while(!stopRequested2) { ++i; } } }); //啟動線程 backgroundThread.start(); //停下1s之後執行變數修改程式 try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } //修改變數 stopRequested2 = true; } public static void main(String[] args) throws InterruptedException { Thread backgroundThread = new Thread(new Runnable() { @Override public void run() { int i = 0; System.out.println(stopRequested); //false //這裡停不下來是因為主線程對stopRequest進行修改的時候,這個線程並不可見 while(!stopRequested) { ++i; } } }); //啟動線程 backgroundThread.start(); //休眠1秒 TimeUnit.SECONDS.sleep(1); stopRequested = true; }}
這個main方法是永遠不停的,其餘兩個從兩個不同的角度給出了同步的方法
總之:當多個線程共用可變資料的時候,每個讀或者寫資料的線程都必須執行同步。