我的主线程启动了一个线程a,a的run里面就是一个死循环不停的向控制台输出。
现在比如主线程是一个用户界面,点击界面的暂停按钮,a就不再输出,点继续接着输出.
用a.wait()在a的run方法执行完之前获取不到线程a对象的锁,但是a的run就是一个死循环,他永远执行不完.
其实真实情况是这样,a的run里面运行的是一段很费时的代码,想随时可以暂停他,也可以继续执行
我的主线程启动了一个线程a,a的run里面就是一个死循环不停的向控制台输出。
现在比如主线程是一个用户界面,点击界面的暂停按钮,a就不再输出,点继续接着输出.
用a.wait()在a的run方法执行完之前获取不到线程a对象的锁,但是a的run就是一个死循环,他永远执行不完.
其实真实情况是这样,a的run里面运行的是一段很费时的代码,想随时可以暂停他,也可以继续执行
可能是因为你的子线程的run方法里面有synchronized(this),run方法一直运行,所以一直没有释放对子线程对象的锁,主线程里面当然获取不到。
即使在主线程中能得到锁,调用子线程对象的wait()方法只能使主线程自身处于等待状态,并不会停止子线程,只有在子线程的run方法里面调用wait()才能让子线程暂定运行,所以你这么做是不行的。
[b]可行的做法是:
1.在子线程对象里面加一个runFlag,run方法运行的时候,每循环一次就检查一下这个runFlag,根据runFlag的状态决定是暂定,还是继续执行,还是退出。
2.主线程里面根据需要去设置子线程对象中的runFlag。
3.暂定的时候,直接更新runFlag即可。
继续运行的时候,更新完runFlag后,还需要调用notify()来通知子线程来解除子线程的wait状态。(因为此时子线程处于wait状态,无法判断runFlag的状态)[/b]
具体可以参照下面的代码:
屏幕输入s,代表暂停子线程的运行。
屏幕输入c,代表子线程继续运行。
屏幕输入e, 代表结束子线程和主线程。
因为主线程和子线程共用同一个console,所以屏幕输出会有些混乱,不过不影响功能。
[code="java"]class SubThread extends Thread{
private int runFlag=1;
public void doStop(){
runFlag = 2;
}
public void doContinue(){
runFlag = 1;
}
public void doExit(){
runFlag = 0;
}
public void run(){
while(runFlag != 0){
if(runFlag == 1){
System.out.println("sub thread is running...");
}else if(runFlag == 2){
synchronized(this){
System.out.println("sub thread is waiting...");
try{
this.wait();
System.out.println("sub thread continue...");
}catch (Exception e)
{
e.printStackTrace();
}
}
}
try{
sleep(1000);
}catch (Exception e)
{
e.printStackTrace();
}
}
System.out.println("sub thread is over");
}
}
public class MainThread
{
public static void main(String[] args)
{
SubThread sthread = new SubThread();
sthread.start();
byte[] b = new byte[10];
String str = "";
while(true){
try{
Thread.sleep(100);
}catch(Exception e){
e.printStackTrace();
}
System.out.print("please input:");
try{
System.in.read(b);
}catch(Exception e){
e.printStackTrace();
}
str = new String(b);
System.out.println(str);
if(str.startsWith("s")){
sthread.doStop();
}else if(str.startsWith("c")){
sthread.doContinue();
synchronized(sthread){
sthread.notify();
}
}else if(str.startsWith("e")){
sthread.doExit();
synchronized(sthread){
sthread.notify();
}
break;
}
}
System.out.println("main thread is over");
}
}[/code]
如果把主线程改成GUI画面的话,那么点击按钮的时候可能需要点击多次,才能获得响应,因为主线程和子线程分时复用CPU资源,你点击按钮的时候,如果GUI主线程此时没有获得时间片,那么可能不会检测到你的点击动作。多点几次肯定就能获得响应。