多线程——Atomic、synchronized、LongAdder(自旋锁、系统锁、分段锁)

Atomic:使用自旋锁,如果线程多,执行时间长会消耗CPU资源,性能消耗在切换线程上,所以如果线程少,执行时间不长,推荐使用自旋锁来保证线程安全。使用场景:线程少,加锁时间短。
Synchronized:系统锁,在没有锁升的情况下属于总量级锁,每次加锁都要向操作系统申请加锁,加锁时间慢,使用该锁存在同步队列,即如果没有抢到锁的线程会加入到队列中,等到锁得到释放才会通知去获取锁,不会导致大量CPU来回切换线程。适用场景:线程数量多,加锁时间长。
LongAdder:分段锁,在多个线程执行时存在多个锁,分别管理多个共享资源,当所有线程都结束后再将这些锁管控的共享资源结果结合起来得到最后结果。使用场景:线程数量多。
注意:实际情况中,使用那种锁机制,还是得提前判定锁的数量和加锁时间,除此以外,最好还是测一测哪个锁的效率高,以决定使用哪种锁机制。

public class TestLock {
    static long count2 = 0L;
    static AtomicLong count1 = new AtomicLong(0L);
    static LongAdder count3 = new LongAdder();

    public static void main(String[] args) throws Exception {
        Thread[] threads = new Thread[1000];

        for(int i=0; i<threads.length; i++) {
            threads[i] =
                    new Thread(()-> {
                        for(int k=0; k<1000000; k++) count1.incrementAndGet();
                    });
        }
        long start = System.currentTimeMillis();
        for(Thread t : threads ) t.start();
        for (Thread t : threads) t.join();
        long end = System.currentTimeMillis();
        System.out.println("Atomic: " + count1.get() + " time " + (end-start));
        //-----------------------------------------------------------
        Object lock = new Object();
        for(int i=0; i<threads.length; i++) {
            threads[i] =
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        for (int k = 0; k < 100000; k++)
                            synchronized (lock) {
                                count2++;
                            }
                    }
                });
        }
        start = System.currentTimeMillis();
        for(Thread t : threads ) t.start();
        for (Thread t : threads) t.join();
        end = System.currentTimeMillis();
        System.out.println("Sync: " + count2 + " time " + (end-start));

        //----------------------------------
        for(int i=0; i<threads.length; i++) {
            threads[i] =
                    new Thread(()-> {
                        for(int k=0; k<100000; k++) count3.increment();
                    });
        }
        start = System.currentTimeMillis();
        for(Thread t : threads ) t.start();
        for (Thread t : threads) t.join();
        end = System.currentTimeMillis();
        System.out.println("LongAdder: " + count1.longValue() + " time " + (end-start));
    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值