synchronized一个用法

具体用法没有总结,只是说明一个用法而已,对于以前个人理解出现的偏差

【问题描述】

对于一个计数功能的实现,获取值的方法是否需要加锁?

【以前理解】

我只需要在进行累加的方法上进行加锁即可,这样保证其可以正确计数即可。对于获取值而言,最大的影响是无法获取当前最新的值而已,其他无影响

【案例测试】

直接上代码。结果差异很大。测试结果中,出现过实际已经计数到几万,但是获取的结果仍然在几百范围内的情况。即使对变量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修饰。

猜你喜欢

转载自www.cnblogs.com/woniu4/p/9130556.html
今日推荐