我是Java编程的新手,我知道Java中的多线程技术不是一个琐碎的话题,而且我作为C开发人员工作了将近3年.
我将代码更新如下:
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 list1 = new ArrayList();
private List list2 = new ArrayList();
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
清单1:2000;清单2:2000
但是,如果我使两个函数(updateList1,updateList2)都同步并删除了lock1和lock2上的同步块
主要将输出:
花费时间:4342
清单1:2000;清单2:2000
问题在于execute()内的代码先调用updateList1(),然后再调用updateList2(),因此这是两个方法的顺序调用,在第一个代码中(使用同步块),如果一个线程获取了lock1,而另一个线程尝试调用updateList1 (),它将等待另一个线程释放lock1.因此,两种实现方式的时间必须相等.
请校准答案,如果我对Java的理解不正确,请对不起,因为这种情况是我从C经验中学到的.
解决方法:
使用同步方法时,在任何给定时间只能执行两种方法之一.这将导致顺序执行,如下所示(当然,还有许多其他可能性):
t1: updateList1 updateList2
t2: updateList1 updateList2
而是在不同的锁对象上使用同步语句,可以使两种方法同时运行.
t1: updateList1 updateList2 updateList1 updateList2
t2: updateList1 updateList2 updateList1
第一步之后,updateList1和updateList2可以并行运行.由于这些方法需要相同的时间,因此在第二种情况下,您也可以获得理想的加速比2.
标签:multithreading,java
来源: https://codeday.me/bug/20191027/1942735.html