我对使用wait()和notify()方法有些怀疑。我有下一个代码,它有一些按钮事件,第一次用户按下它必须停止打印的按钮,第二次重新开始打印。我知道最好使用Runnable而不是Thread,但由于要求我必须使用Thread。第一次按下按钮时代码工作正常,但第二次没有,我想使用wait()和notify,但我不知道如何使用这个特定的代码。
class Thr extends Thread{
private int count = 0;
private long pause;
private boolean canPrint = true;
private JTextArea textArea;
Thr(long miliseconds,JTextArea text){
pause = miliseconds;
textArea = text;
}
public void pushedButton(){
if(canPrint)
this.canPrint = false;
else
this.canPrint = true;
}
public void run()
{
while(this.canPrint)
{
try
{
this.printCounter();
Thread.sleep(pause);
this.count++;
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
public void printCounter(){
String time;
time = Integer.toString(count);
textArea.setText(time);
}
}
class Interface extends JFrame implements ActionListener{
private JTextArea textArea,textArea2;
private JButton button;
private Thr thread,threadEvent;
Interface()
{
textArea = new JTextArea(10,7);
textArea2 = new JTextArea(10,7);
thread = new Thr(2000,textArea);
threadEvent = new Thr(1000,textArea2);
button = new JButton("Pausar/Reanudar");
this.getContentPane().add(button,BorderLayout.SOUTH);
this.getContentPane().add(textArea,BorderLayout.WEST);
this.getContentPane().add(textArea2,BorderLayout.EAST);
thread.start();
threadEvent.start();
button.addActionListener(this);
}
public void actionPerformed(ActionEvent event)
{
threadEvent.pushedButton();
}
}
public class MensajesHilos {
public static void main(String[] args){
Interface i = new Interface();
i.setTitle("Control Threads");
i.setBounds(200, 200, 300, 240);
i.setVisible(true);
}
}
答案 0 :(得分:0)
您编码的方式,如果您想获得所需的结果,
我觉得修改需要在run方法中完成,
public void run()
{
while(true)
{
if(this.canPrint){
try
{
this.printCounter();
Thread.sleep(pause);
this.count++;
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
通过这种方式,您的线程永远不会死亡,并根据canPrint布尔值切换打印。
另外,请确保声明canPrint变量volatile
,以便对其进行更改直接写入主内存并立即反映。
答案 1 :(得分:0)
“按钮事件无法正常工作”
这是假的,如果你在actionPerformed
方法中放置一个print语句,你会看到每次按下按钮都会调用它。
请注意,您可以简化此
if(canPrint)
this.canPrint = false;
else
this.canPrint = true;
要
this.canPrint = !this.canPrint;
请注意,始终将@Override
anotation置于覆盖方法之上是一种好习惯。
@Override
public void actionPerformed(ActionEvent event)
{
threadEvent.pushedButton();
}
现在为什么不能得到预期的结果?
您忘记致电thread.pushedButton
,因此canPrint
只会在threadEvent
对象中重置,永远不会在thread
。
请注意,一旦布尔值设置为false,您将退出loop
,即使您将布尔值重新设置为true
,该过程也不会重新启动。此示例将使用while(true)
,但是,您应该将true
更改为任何sentinel值以处理程序的退出,因为这将永远循环。
@Override
public void run()
{
while(true)
{
if(this.canPrint)
{
this.printCounter();
this.count++;
}
try
{
Thread.sleep(pause);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
另外,请确保pause
永远不会为0,否则您将吃掉所有计算机进程。
请注意,正如其他所述,您应该在您的案例中将在线程中访问的变量声明为volatile
(canPrint)。