美文网首页
两个线程交替执行+1,无锁化实现和synchronized 、c

两个线程交替执行+1,无锁化实现和synchronized 、c

作者: 窗外的季节 | 来源:发表于2019-03-21 17:02 被阅读0次

    今天面试阿里被问到一个简单的多线程问题,脑子里第一个闪现的是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,效率差距明显

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

    相关文章

      网友评论

          本文标题:两个线程交替执行+1,无锁化实现和synchronized 、c

          本文链接:https://www.haomeiwen.com/subject/otjnvttx.html