为了账号安全,请及时绑定邮箱和手机立即绑定

同步关键字Java速度效率

同步关键字Java速度效率

慕森王 2021-08-04 10:08:33
如果我错了,请随时纠正我!java中的synchronized关键字使得一个方法不能同时在不同的线程中运行。在我的程序中,我有 4 个不同的线程同时运行,计数到 100.000。将 synchronized 关键字添加到正在执行的方法中时,它的时间应该是多线程的四倍?无论以哪种方式执行程序,大约需要 16 秒。这是我的代码!public class ExerciseThree {    public static void main(String[] args) {        Even even = new Even();        Thread t1 = new Thread(() -> {            for (int i = 0; i < 100000; i++) {                System.out.println(even.next());            }        });        Thread t2 = new Thread(() -> {            for (int i = 0; i < 100000; i++) {                System.out.println(even.next());            }        });        Thread t3 = new Thread(() -> {            for (int i = 0; i < 100000; i++) {                System.out.println(even.next());            }        });        Thread t4 = new Thread(() -> {            for (int i = 0; i < 100000; i++) {                System.out.println(even.next());            }        });        System.out.println("starting thread 1");        t1.start();        System.out.println("starting thread 2");        t2.start();        System.out.println("starting thread 3");        t3.start();        System.out.println("starting thread 4");        t4.start();    }}线程调用的方法public class Even {        private int n = 0;//      public synchronized int next() {        public int next() {            n++;            n++;            return n;        }    }
查看完整描述

2 回答

?
肥皂起泡泡

TA贡献1829条经验 获得超6个赞

微基准测试是一个复杂的问题,因为影响执行时间的因素有很多(例如,即时编译和垃圾收集)。评论部分已经提供了一个很好的参考,但我建议您也看看我对类似问题的回答,该问题链接到Peter Setoft的外部资源,该资源提供了对微基准测试的非常好的介绍以及需要做什么意识到。


已经提到println()在这样的微基准测试中没有位置。此外,我想指出您应该使用某种同步机制(例如, a CountDownLatch)来确保四个线程同时开始执行它们的工作。创建和启动线程所涉及的开销可能会导致较早的线程在后面的线程启动所需的时间内抢占先机,从而导致对even锁的争用比您预期的要少。例如,这可能看起来像这样:


public class ExerciseThree {


    public static void main(String[] args) {

        final CountDownLatch startSignal = new CountDownLatch(1);

        final CountDownLatch threadReadyCheck = new CountDownLatch(4);

        final CountDownLatch threadDoneCheck = new CountDownLatch(4);

        Even even = new Even();

        Thread t1 = new Thread(() -> {

            threadReadyCheck.countDown();

            startSignal.await();

            for (int i = 0; i < 100000; i++) {

                even.next();

            }

            threadDoneCheck.countDown();

        });

        Thread t2 = new Thread(() -> {

            threadReadyCheck.countDown();

            startSignal.await();

            for (int i = 0; i < 100000; i++) {

                even.next();

            }

            threadDoneCheck.countDown();

        });

        Thread t3 = new Thread(() -> {

            threadReadyCheck.countDown();

            startSignal.await();

            for (int i = 0; i < 100000; i++) {

                even.next();

            }

            threadDoneCheck.countDown();

        });

        Thread t4 = new Thread(() -> {

            threadReadyCheck.countDown();

            startSignal.await();

            for (int i = 0; i < 100000; i++) {

                even.next();

            }

            threadDoneCheck.countDown();

        });

        t1.start();

        t2.start();

        t3.start();

        t4.start();

        // Wait until all threads are ready to perform their work.

        threadReadyCheck.await();

        // All threads ready.

        // This is where you log start time.

        long start = System.nanoTime();

        // Let threads progress to perform their actual work.

        startSignal.countDown();

        // Wait for threads to finish their work.

        threadDoneCheck.await();

        long end = System.nanoTime();

        // Note that this is again subject to many factors, for example when the main thread gets scheduled again after the workers terminate.

        long executionTime = end - start;

    }

}



查看完整回答
反对 回复 2021-08-04
  • 2 回答
  • 0 关注
  • 136 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信