【发布时间】:2016-07-03 15:30:52
【问题描述】:
所以这里是代码。 基本上,如果我们将 ReadCalculation 和 Calculator 类更改为扩展 Thread 而不是实现 Runnable,我们将需要实例化这些类并将它们传递给新的线程对象,或者只对它们调用 start()。
Calculator calc = new Calculator();
new ReadCalculation(calc).start();
new ReadCalculation(calc).start();
calc.start();
到目前为止没有什么特别的.. 但是当你执行这个小程序时,如果我们通过扩展 Thread 类来讨论 Runnable 实现,那么你的线程很有可能会一直被阻塞“等待计算......”。
如果我们扩展 Thread 类而不是实现 Runnable,则行为是正确的,没有任何竞争条件的迹象。 任何想法可能是这种行为的根源?
public class NotifyAllAndWait {
public static void main(String[] args) {
Calculator calc = new Calculator();
Thread th01 = new Thread(new ReadCalculation(calc));
th01.start();
Thread th02 = new Thread(new ReadCalculation(calc));
th02.start();
Thread calcThread = new Thread(calc);
calcThread.start();
}
}
class ReadCalculation implements Runnable {
private Calculator calc = null;
ReadCalculation(Calculator calc) {
this.calc = calc;
}
@Override
public void run() {
synchronized (calc) {
try {
System.out.println(Thread.currentThread().getName() + " Waiting for calculation...");
calc.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " Total: " + calc.getTotal());
}
}
}
class Calculator implements Runnable {
private int total = 0;
@Override
public void run() {
synchronized(this) {
System.out.println(Thread.currentThread().getName() + " RUNNING CALCULATION!");
for(int i = 0; i < 100; i = i + 2){
total = total + i;
}
notifyAll();
}
}
public int getTotal() {
return total;
}
}
【问题讨论】:
-
我不能引用语言或 JVM 规范的任何部分,这可能在这里起作用,但最可能的实际原因是
Thread的源代码在 @ 987654324@ 和当前Thread实例。您可以从calc的内部和外部锁定计算器实例。当您使用专用目标 Runnable 时,这些锁可能不会干扰Thread内部的锁定(刚刚检查过:Android Thread 实现中的代码似乎不会锁定传递的 Runnable),但当您扩展 Thread 时肯定会影响执行顺序。跨度>
标签: java multithreading runnable race-condition synchronized