Java-同步方法导致程序大量减慢 [英] Java - Synchronized methods causes program to slow down massively

查看:134
本文介绍了Java-同步方法导致程序大量减慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试了解线程和同步.我编写了这个测试程序:

I'm trying to learn about threads and synchronization. I made this test program:

public class Test {
    static List<Thread> al = new ArrayList<>();

    public static void main(String[] args) throws IOException, InterruptedException {
        long startTime = System.currentTimeMillis();

        al.add(new Thread(() -> fib1(47)));
        al.add(new Thread(() -> fib2(47)));

        for (Thread t : al)
            t.start();
        for (Thread t: al)
            t.join();

        long totalTime = System.currentTimeMillis() - startTime;
        System.out.println(totalTime);
    }

    public static synchronized int fib1(int x) {
        return x <= 2 ? 1 : fib1(x-2) + fib1(x-1);
    }

    public static synchronized int fib2(int x) {
        return x <= 2 ? 1 : fib2(x-2) + fib2(x-1);
    }
}

此程序大约需要273秒才能完成,但是如果我同时删除了两个synchronized,它将在7秒内运行.是什么原因导致这种巨大差异?

This program takes around 273 seconds to finish, but if I remove both of the synchronized it runs in 7 seconds instead. What causes this massive difference?

我知道我正在使用非常慢的算法来计算斐波那契数.而且我也知道线程不共享资源,因此不需要同步方法.但是,这只是一个测试程序,在这里我试图弄清楚synchronized的工作方式,我故意选择一种慢速算法,以便可以以毫秒为单位测量时间.

I'm aware that I'm using a terribly slow algorithm for calculating fibonacci numbers. And I'm also aware that the threads don't share resources and thus the methods don't need to be synchronized. However, this is just a test program where I'm trying to figure out how synchronized works and I choose a slow algorithm on purpose so I could measure time taken in milliseconds.

推荐答案

static synchronized放在方法上意味着,为了使线程执行该方法,它首先必须获取该类的锁. (这里是测试).两种静态fib方法使用相同的锁.一个线程获取该锁,执行fib方法,然后释放该锁,然后另一个线程获取执行该方法.哪个线程首先获得锁定取决于操作系统.

When you put static synchronized on a method that means that, in order for a thread to execute that method, it first has to acquire the lock for the class (which here is Test). The two static fib methods use the same lock. One thread gets the lock, executes the fib method, and releases the lock, then the other thread gets to execute the method. Which thread gets the lock first is up to the OS.

已经提到过,锁是可重入的,并且递归调用同步方法没有问题.线程从第一次调用fib方法开始就一直持有该锁,该调用直到所有递归调用都完成才完成,因此该方法在线程释放锁之前一直运行到完成.

It was already mentioned the locks are re-entrant and there's no problem with calling a synchronized method recursively. The thread holds the lock from the time it first calls the fib method, that call doesn't complete until all the recursive calls have completed, so the method runs to completion before the thread releases the lock.

主线程除了等待外什么都不做,一次只能调用fib方法的线程之一.确实有意义的是,删除同步修饰符可以加快速度,而无需锁定两个线程就可以并发运行,可能使用不同的处理器.

The main thread isn't doing anything but waiting, and only one of the threads calling a fib method can run at a time. It does make sense that removing the synchronized modifier would speed up things, without locking the two threads can run concurrently, possibly using different processors.

这些方法不会修改任何共享状态,因此没有理由对其进行同步.即使确实需要同步它们,也没有理由在这里拥有两个单独的fib方法,因为无论如何调用fib1或fib2方法都需要获取相同的锁.

The methods do not modify any shared state so there's no reason to synchronize them. Even if they did need to be synchronized there would still be no reason to have two separate fib methods here, because in any case invoking either the fib1 or fib2 method requires acquiring the same lock.

在没有静态的情况下使用同步意味着将对象实例(而不是类)用作锁.所有同步方法都使用同一锁的原因在于,重点是要保护共享状态,一个对象可能具有各种方法来修改该对象的内部状态,并且为了防止该状态受到并发修改的影响,最多应执行一个线程.一次使用这些方法中的任何一种.

Using synchronized without static means that the object instance, not the class, is used as the lock. The reason that all the synchronized methods use the same lock is that the point is to protect shared state, an object might have various methods that modify the object's internal state, and to protect that state from concurrent modifications no more than one thread should be executing any one of these methods at a time.

这篇关于Java-同步方法导致程序大量减慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆