具体用法没有总结,只是说明一个用法而已,对于以前个人理解出现的偏差
【问题描述】
对于一个计数功能的实现,获取值的方法是否需要加锁?
【以前理解】
我只需要在进行累加的方法上进行加锁即可,这样保证其可以正确计数即可。对于获取值而言,最大的影响是无法获取当前最新的值而已,其他无影响
【案例测试】
直接上代码。结果差异很大。测试结果中,出现过实际已经计数到几万,但是获取的结果仍然在几百范围内的情况。即使对变量i用volatile修饰,仍然无法避免。
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++;//在java中非原子操作,包含一次读取,一次写入,并且中间还夹杂着相加的操作,因此在并发问题上比较容易出现问题 i++; System.out.println(i); } @Override public void run() { while(true) { evenIncrement(); } } public static void main(String[] args) throws InterruptedException { ExecutorService exec = Executors.newCachedThreadPool(); AtomicityTest at = new AtomicityTest(); exec.execute(at); Thread.sleep(1); while(true) { int val = at.getValue(); if(val % 2 != 0) { System.out.println(val + " not even"); System.exit(0); } } } }
【总结】
对于这类问题,最好的办法,就是对两种方法均通过synchronized修饰。