【发布时间】:2016-03-21 08:00:25
【问题描述】:
我是 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 语言经验中了解到的。
【问题讨论】:
标签: java multithreading