我在SO上遇到了关于java多线程的几乎所有问题,但我不太明白我的理解是否正确。
我希望了解操作顺序是否如下所述。
import javax.swing.*;
import java.awt.FlowLayout;
import java.awt.event.*;
class Runner implements Runnable{
long count = 0;
JLabel label;
boolean paused = false;
public Runner(JLabel label){
this.label = label;
}
public void run(){
while(true){
try {
if(paused){
synchronized(this){
wait();
}
}
} catch(InterruptedException e) {}
count++;
label.setText(Long.toString(count));
if(Thread.interrupted())
return;
}
}
synchronized void pause_counting(){
paused = true;
}
synchronized void start_counting(){
paused = false;
notifyAll();
}
}
public class ThreadRace extends JApplet{
boolean running = true;
Thread thread;
@Override
public void init(){
final JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
JLabel threadProgress = new JLabel("0");
final Runner runner = new Runner(threadProgress);
thread = new Thread(runner);
thread.start();
panel.add(threadProgress);
JButton toggle = new JButton("Stop");
toggle.addActionListener(new ActionListener() {
@Override
synchronized public void actionPerformed(ActionEvent e) {
System.out.println("Running: " + running);
if(running){
runner.pause_counting();
} else {
runner.start_counting();
}
running = !running;
}
});
panel.add(toggle);
add(panel);
}
public void stop(){
thread.interrupt();
}
}
这是如何运作的?
pause_counting()
时,我设置为暂停为假。runner
块内对象synchronized(this) { ... }
的锁定。this.wait()
时,我释放了我刚刚占有的同一个锁并进入WAITING
状态。runner
(!)start_counting()
。RUNNING
状态,并在wait()语句之后继续。虽然它仍然位于synchronized(this)
块内,但它会锁定锁我很确定我的理解存在一些缺陷。
帮助? :(
答案 0 :(得分:2)
这是如何运作的?
是。所有的陈述都适用于一些调整(见下文)。
但是,您的程序中存在错误。由于该线程在paused
块内而不是时正在测试synchronized
,因此您需要确保paused
为volatile
以提供内存同步。
volatile boolean paused = false
对于JLabel
数组,这可能也是必要的。只要有线程正在更改共享变量,就需要进行内存同步。
当我调用方法pause_counting()时,我设置为暂停为假。
是。在此处更新paused
即可,因为它采用synchronized
方法。
在run()内部,我抓住了一个对象,在同步(this){...}块内的runner [i]。
仅当paused
为真时。由于您要在paused
块之外测试synchronized
,因此paused
需要volatile
以确保线程之间的内存同步。
当我调用this.wait()时,我释放了我刚刚占有的同一个锁并进入WAITING状态。
右。
此时,任何其他方法都可以自由地使用此跑步者[i](!)
之前可以自由地执行操作,但是现在已经释放了锁,它可以在不阻塞的情况下调用synchronized
方法。
我最终打电话给start_counting()。
右。这会调用notifyAll()
。
这使线程返回RUNNING状态,并在wait()语句之后继续。虽然它仍在同步(此)块内,但它会锁定锁
首先,它使线程进入BLOCKED
状态,直到start_counting()
的调用者离开该方法并释放锁。
但是,一旦它离开块,它就会释放锁并继续执行
右。