數據類:
package Thread.MyCommon; public class Data { public int num = 0; public synchronized int getEven() { ++num; Thread.yield();//讓另外線程先執行,加大測試效果幾率 ++num; return num; } }
線程類:
package Thread.MyCommon; public class myThread implements Runnable { private Data data; public myThread(Data d) { data = d; } @Override public void run() { while (true) { int val = data.getEven(); if (val % 2 != 0) { System.out.println(val + " not even!"); } } } }
主線程類:
package Thread.MyCommon; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Main { public static void main(String[] args) { Data data=new Data();//多個線程操作的是同一個對象 ExecutorService executorService=Executors.newCachedThreadPool(); for (int i = 0; i < 10; i++) { executorService.execute(new myThread(data)); } executorService.shutdown();//關閉線程池,如果不關閉線程池將一直運行。 } }
------------------------------------------------------------------------------------------
可以將同步代碼改用lock方式:
package Thread.MyCommon; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class Data { public int num = 0; Lock lock = new ReentrantLock(); public int getEven() { lock.lock(); try { ++num; Thread.yield();// 讓另外線程先執行,加大測試幾率 ++num; return num;// 一定要在unlock之前return,否則數據不同步 } finally { lock.unlock(); } // return num;//不能在unlock之后return,否則數據不同步 } }
或者改成 synchronized (this)
package Thread.MyCommon; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class Data { public int num = 0; Lock lock = new ReentrantLock(); public int getEven() { synchronized (this) { ++num; Thread.yield();// 讓另外線程先執行,加大測試幾率 ++num; return num;// 一定要在unlock之前return,否則數據不同步 } } }
--------------------------------------------------------------------------
以下寫法,雖然已經同步,但是讀取方法不能保證數據是同步的偶數
package Thread.MyCommon; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class AtomicityTest implements Runnable { private int i = 0; public int getValue() { return i; } private synchronized void evenIncrement() { i++; Thread.yield(); i++; } @Override public void run() { while (true) evenIncrement(); } public static void main(String[] args) { ExecutorService exec = Executors.newCachedThreadPool(); AtomicityTest at = new AtomicityTest(); exec.execute(at); while (true) { int val = at.getValue(); if (val % 2 != 0) { System.out.println(val); System.exit(0); } } } }