Java多线程之简单的线程同步实例
数据类:
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); } } } }