多线程并发锁和原子操作

本文深入探讨了Java多线程并发中的常见问题,包括synchronized与tryLock的使用,以及原子类的作用。通过实例代码分析,揭示了在并发编程中避免同步问题的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我是看了这篇文章后总结一下问题,希望以后能够注意这些问题:


package w0141112;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * User: zhijun.he@renren-inc.com
 * Date: 2014/11/12.
 */
public class TestMultiThread implements Runnable {
    private static int i;
    private static volatile Integer vi = 0;
    private static AtomicInteger ai = new AtomicInteger();
    private static Integer si = 0;
    private static int ri;
    private static AtomicInteger flag = new AtomicInteger();
    private Lock lock = new ReentrantLock();

    public void run() {
        for (int k = 0; k < 200000; k++) {
            i++;
            vi++;
            ai.incrementAndGet();
            synchronized (si) {
                si++;
            }
            lock.lock();
            try {
                ri++;
            } finally {
                lock.unlock();
            }
        }
        flag.incrementAndGet();
    }

    public static void main(String[] args) throws InterruptedException {
        TestMultiThread t1 = new TestMultiThread();
        TestMultiThread t2 = new TestMultiThread();
        ExecutorService exec1 = Executors.newCachedThreadPool();
        ExecutorService exec2 = Executors.newCachedThreadPool();
        exec1.execute(t1);
        exec2.execute(t2);
        while (true) {
            if (flag.intValue() == 2) {
                System.out.println("i " + i);
                System.out.println("vi " + vi);
                System.out.println("ai " + ai);
                System.out.println("si " + si);
                System.out.println("ri " + ri);
                break;
            }
            Thread.sleep(50);
        }
        exec1.shutdown();
        exec2.shutdown();
    }
}

输出:

i 398728
vi 363257
ai 400000
si 355444
ri 396292


问题:

1.奇怪的是synchronized并没有起到多线程的加锁效果

2.try lock貌似也没有

3.原子类起到了作用(因为它是线程安全的,是用CAS实现的)


解释:

1.原博客的解释我是没看懂,或许是java存在的缺陷。但是我想说的是如何避免这个问题,这才是我真正关心的。现实编码中,其实你根本不会出现这种情况,为什么呢?因为一般代码从来没有可能对于锁去进行操作。也就是指

synchronized (si) {
    si++;
}
完全可以用其他静态字段代替synchronized(si)


2.try lock没起作用这真的是原作者写错了,如果把字段改成静态就ok了。

private static Lock lock = new ReentrantLock();






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值