两个线程交替执行+1,无锁化实现和synchronized 、condition实现的效率对比

今天面试阿里被问到一个简单的多线程问题,脑子里第一个闪现的是wait()和notify(),写代码的时候又蹦出些其它想法,结果写的时间有点长,实现也有点混乱,回来后把当时的想法整理了一下,分别比较一下实现效率。

1.synchronized + wait +notify

这个实现可以看连接https://blog.csdn.net/woainiwss/article/details/52013810

2.condition + await + signal

private static ReentrantReadWriteLock lock = new ReentrantReadWriteLock();private static Condition condition = lock.writeLock().newCondition();private static final void runCount(Boolean ood) throws InterruptedException {    for (int i = 0; i<100001;i++) {lock.writeLock().lock();if(ood){if(i%2==1){//System.out.println(i);condition.await();continue;            }else{condition.signal();            }        }else{if(i%2==0){//System.out.println(i);condition.await();continue;            }else{condition.signal();            }        }lock.writeLock().unlock();if(i==100000){System.out.println(System.currentTimeMillis());        }    }}

3.AtomicInteger + while循环

private static  volatile AtomicInteger count = new AtomicInteger(0);

    private static final void spinCount(Boolean odd ){

        while (true){

            if(odd && count.get()%2 == 0){

                //System.out.println(count.get());

                if(count.incrementAndGet() == 100001){

                    System.out.println(System.currentTimeMillis());

                    return;

                }

            }else if(!odd && count.get()%2 == 1){

                //System.out.println(count.get());

                count.incrementAndGet();

            }

        }

    }

最后调用

public static void main(String[] args) {

    Thread t1 = new Thread(new Runnable() {

        @Override

        public void run() {

            try {

                runCount(false);

                //spinCount(false);

                //syncCount1();

            } catch (Exception e) {

                e.printStackTrace();

            }

        }

    });

    Thread t2 = new Thread(new Runnable() {

        @Override

        public void run() {

            try {

                runCount(true);

                //spinCount(true);

                //syncCount2();

            } catch (Exception e) {

                e.printStackTrace();

            }

        }

    });

    System.out.println(System.currentTimeMillis());

    t1.start();

    t2.start();

}

循环次数小的情况下效率上 第一种>第二种>第三种。

在循环次数较少的时候JDK自己控制的synchronized关键字效率最高,看起来无锁化的第三种反而效率最低。 第二种用condition实现的代码会优雅些,但是效率差一点点。另外我直接把第二种的代码换成synchronized来实现的话,次数稍微多点就会出现死锁,说明新的juc对锁的控制上要更好点。

循环次数大的情况下效率上 第三种 > 第一种 > 第二种。

随着次数增加 前两种加锁的要比循环的消耗时间增长的快。在10W次的时候,第一种550ms,第二种605ms,而第三种只需要25ms,效率差距明显

这三种只是我的一点拙见,希望能抛砖引玉,有谁能提供更好的思路,谢谢

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容