gpt4 book ai didi

java - 不同对象锁上的多线程

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:06:28 28 4
gpt4 key购买 nike

我是 java 编程的新手,我知道多线程在 Java 中不是一个微不足道的话题,而且我作为 C 开发人员工作了将近 3 年。

我读过这个主题:“Multiple locks - Behind the scene”,我完全理解它,但我有一个顾虑。

我更新代码如下:

package multithreading;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Worker {

private List<Integer> list1 = new ArrayList<Integer>();
private List<Integer> list2 = new ArrayList<Integer>();

private Object lock1 = new Object();
private Object lock2 = new Object();

private void updateList1(int i) {
synchronized (lock1) {
try {
Thread.sleep(1);
} catch (InterruptedException ex) {
Logger.getLogger(Worker.class.getName()).log(Level.SEVERE, null, ex);
}
list1.add(1);
}
}

private void updateList2(int i) {
synchronized (lock2) {
try {
Thread.sleep(1);
} catch (InterruptedException ex) {
Logger.getLogger(Worker.class.getName()).log(Level.SEVERE, null, ex);
}
list2.add(1);
}
}

public void process(int ii) {
for (int i = 0; i < 1000; i++) {
updateList1(ii);
updateList2(ii);
}
}

public void execute() {
Thread t1 = new Thread(new Runnable() {

@Override
public void run() {
process(1);
}
});

Thread t2 = new Thread(new Runnable() {

@Override
public void run() {
process(2);
}
});

long start = System.currentTimeMillis();

t1.start();
t2.start();

try {
t1.join();
t2.join();
} catch (InterruptedException ex) {
Logger.getLogger(Worker.class.getName()).log(Level.SEVERE, null, ex);
}

long end = System.currentTimeMillis();

System.out.println("Time taken: " + (end - start));
System.out.println("List1: " + list1.size() + "; list2: " + list2.size());
}
}

在主类中,我创建了一个对象并调用了 execute 方法,输出为:

耗时:2186
list 1:2000;列表 2:2000

但是,如果我将两个函数(updateList1、updateList2)设为同步,并删除了lock1lock2 上的同步块(synchronized block)

主要输出:

耗时:4342
list 1:2000;列表 2:2000

问题是 execute() 中的代码调用了 updateList1() 然后是 updateList2() 所以它是对这两个方法的顺序调用, 在第一个代码中(使用 synchronized block )如果一个线程获取了 lock1 而另一个线程试图调用 updateList1() 它将是等待另一个线程释放 lock1。所以两种实现方式的时间必须相等。

请确认答案,如果我对 Java 的理解有任何错误,我深表歉意,因为这种情况是我从 C 语言的经验中了解到的。

最佳答案

对于同步方法,在任何给定时间只能执行两种方法中的一种。这导致如下顺序执行(当然还有许多其他可能性):

t1: updateList1             updateList2
t2: updateList1 updateList2

改为在不同的锁定对象上使用同步语句,允许两种方法同时运行。

t1: updateList1 updateList2 updateList1 updateList2 
t2: updateList1 updateList2 updateList1

经过初始步骤后,updateList1updateList2 可以并行运行。由于这两种方法需要相同的时间,因此在第二种情况下您也可以获得理想的 2 倍加速。

关于java - 不同对象锁上的多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36125723/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com