我是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方法,输出为:
Time taken: 2186
List1: 2000; list2: 2000
但是,如果我使两个函数(updateList1,updateList2)都为synchronized
并删除lock1
和lock2
上的同步块
主要输出:
Time taken: 4342
List1: 2000; list2: 2000
关注的是execute()
调用updateList1()
内的代码,然后是updateList2()
,因此它是对第一个代码(使用synchronized
块)中的两个方法的顺序调用一个线程获取lock1
而另一个线程试图调用updateList1()
它将等待另一个线程释放lock1
。因此,两种实施方式的时间必须相同。
请理解答案,如果我在Java中有任何错误理解,请对不起,因为这个场景是我从C的经验中得知的。
答案 0 :(得分:2)
使用synchronized方法,在任何给定时间只能执行两种方法中的一种。这导致顺序执行如下(当然还有许多其他可能性):
t1: updateList1 updateList2
t2: updateList1 updateList2
在不同的锁定对象上使用synchronized语句,允许两种方法同时运行。
t1: updateList1 updateList2 updateList1 updateList2
t2: updateList1 updateList2 updateList1
初始步骤updateList1
和updateList2
可以并行运行。由于这些方法需要相同的时间,因此在第二种情况下也可以获得理想的加速比率。
答案 1 :(得分:1)
时间不一样,因为在你使updateList1
和updateList2
同步的情况下,他们使用Worker
对象作为锁定实例。
所以在第二种情况下,如果一个线程正在运行updateList2
,则另一个线程无法进入updateList1
。
答案 2 :(得分:1)