如何暂停并稍后继续一个线程的执行

cozmic 2005-07-30 09:37:20
如何暂停并稍后继续一个线程的执行?
比如:一个从1到10000的累加程序,我想让程序运行100ms时,暂停执行;
1100m后继续执行。
给思路的,介绍书目的都有分~
呵呵,给出解决代码的,那就不用说了:P
...全文
867 34 打赏 收藏 转发到动态 举报
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
cozmic 2005-07-31
  • 打赏
  • 举报
回复
不好意思,代码格式太乱了,不知道怎么才能弄好~
cozmic 2005-07-31
  • 打赏
  • 举报
回复
TO: mooninsun
以下是我的代码,但是,不知为什么没有产生效果。

# import java.util.*;
#
# class CanPause extends Thread {
# // 从0累加到10000
# private int counter = 0;
# public void run() {
# while(counter < 10000) {
# System.out.print(counter++ + " ");
# }
# }
# }
#
# public class Pausing {
# public static void main(String[] args) {
# final CanPause pauseable = new CanPause();
# pauseable.start();
# //100ms 后,暂停程序执行
# new Timer(true).schedule(new TimerTask() {
# public void run() {
# System.out.println("start waiting----------------\n");
# synchronized(CanPause.class) {
# try {
# pauseable.wait();
# } catch(Exception e ){}
# }
# }
# }, 100);
# // 400ms后,恢复执行
# new Timer(true).schedule(new TimerTask() {
# public void run() {
# System.out.println("start notifying--------------\n");
# synchronized(CanPause.class) {
# pauseable.notifyAll();
# }
# }
# }, 500);
# }
# }
#
cozmic 2005-07-31
  • 打赏
  • 举报
回复
谢谢!
cozmic 2005-07-31
  • 打赏
  • 举报
回复
代码如下:
--------------------
import java.util.*;

class CanPause extends Thread {
// 从0累加到10000
private int counter = 0;
public void run() {
while(counter < 10000) {
System.out.print(counter++ + " ");
//暂停100ms(仿照mooninsun的:P)
try {
Thread.sleep(100);
} catch(Exception e ){}
}
}
}

public class Pausing1 {
public static void main(String[] args) {
final Boolean semo = new Boolean(true);
final CanPause pauseable = new CanPause();
pauseable.start();
//1s 后,暂停程序执行
new Timer(true).schedule(new TimerTask() {
public void run() {
System.out.println("\nstart waiting------------------------------------\n");
synchronized(CanPause.class) {
try {
pauseable.wait();
} catch(Exception e ){}
}
}
}, 1000);
try {
Thread.sleep(2000);
} catch(Exception e ){}

// 5.5s后,恢复执行
new Timer(true).schedule(new TimerTask() {
public void run() {
System.out.println("\nstart notifying------------------------------------\n");
synchronized(CanPause.class) {
pauseable.notifyAll();
}
}
}, 5500);
}
}
cozmic 2005-07-31
  • 打赏
  • 举报
回复
我的代码运行结果如下:
-------------------------------------------
E:\java\Thread>java Pausing
0 1 2 3 4 5 6 7 8 9
start waiting------------------------------------(*没有任何等待就打印出10)

10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
74
start notifying------------------------------------(没有任何等待就打印出以下)

Exception in thread "Timer-1" java.lang.IllegalMonitorStateException: current
read not owner
at java.lang.Object.notifyAll(Native Method)
at Pausing1$2.run(Pausing1.java:41)
at java.util.TimerThread.mainLoop(Unknown Source)
at java.util.TimerThread.run(Unknown Source)
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
91 92 93 94 95 96 97 98 99 100 101 102 (*Ctrl+c结束)
为什么,线程并没有等待?是不是因为没有等待,导致后来的notifyALl()没有获得Canpause.class
的锁?
cozmic 2005-07-31
  • 打赏
  • 举报
回复
To: mooninsun
谢谢:P
但是还想问一点:为什么在我的代码中,用wait() 和 notifyAll() 就是不可以呢?
asper 2005-07-31
  • 打赏
  • 举报
回复
设置一个标记
事件发生时改写标记
kingarden 2005-07-31
  • 打赏
  • 举报
回复
可以用wait(),notify()方法,当你执行N秒钟后调用这两个函数,让线程停一段时间然后调用它把线程唤醒继续执行即可.
mooninsun 2005-07-31
  • 打赏
  • 举报
回复
改用wait()和notify(),功能没变
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

class TText
extends Thread {
private JTextField t = new JTextField(15);
private JButton bp = new JButton("pause");
private int count = 0;
private boolean startf = false, pus = false;
public TText(Container c) {
c.add(t);
bp.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
pus = true;
}
});
c.add(bp);
new TNotify(c, this);
start();
}

public void StartT() {
startf = true;
}

public synchronized void run() { //注意synchronized,不然会产生
//异常IllegalMonitorStateException
while (true) {
if (startf) {
t.setText(Integer.toString(count++));
}
try {
if(pus) {
wait(); //改用wait();
pus = !pus;
}
sleep(100);
}
catch (InterruptedException e) {
System.err.println("Interrupted");
}
}
}
}

class TNotify
extends Thread {
private TText t;
private boolean startf;
private JButton br = new JButton("resume");
public TNotify(Container c, TText t) {
this.t = t;
br.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
StartT();
}
});
c.add(br);
start();
}
public void StartT() {
startf = true;
}
public void run() {
while (true) {
if (startf) {
synchronized(t) { //注意synchronized,不然会产生
//异常IllegalMonitorStateException
t.notify();
}
startf = !startf;
}
try {
sleep(100);
}
catch (InterruptedException e) {
System.err.println("Interrupted");
}
}
}
}

public class ThreadT
extends JFrame {
private JButton
bs = new JButton("start");
private JPanel p = new JPanel();
private TText t;
private TNotify tn;
public ThreadT() throws HeadlessException {
super("Test");
this.setSize(300, 200);
Container cp = getContentPane();
cp.setLayout(new FlowLayout());
t = new TText(cp);
bs.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
t.StartT();
}
});
cp.add(bs);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

}

public static void main(String[] args) throws HeadlessException {
ThreadT threadT1 = new ThreadT();
}
}
www2005www 2005-07-31
  • 打赏
  • 举报
回复
能用wait()和notify()实现吗
mooninsun 2005-07-31
  • 打赏
  • 举报
回复
TText是一个线程,用TextField来不停的显示递增的数字
而TNotify是一个唤醒线程,由TText调用
主线程用来启动TText
mooninsun 2005-07-31
  • 打赏
  • 举报
回复
顺便帮你写了另一个程序
和你的功能差不多的
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

class TText
extends Thread {
private JTextField t = new JTextField(15);
private JButton bp = new JButton("pause");
private int count = 0;
private boolean startf = false;
public TText(Container c) {
c.add(t);
bp.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
suspend();
}
});
c.add(bp);
new TNotify(c, this);
start();
}

public void StartT() {
startf = true;
}

public void run() {
while (true) {
if (startf) {
t.setText(Integer.toString(count++));
}
try {
sleep(100);
}
catch (InterruptedException e) {
System.err.println("Interrupted");
}
}
}
}

class TNotify
extends Thread {
private TText t;
private boolean startf;
private JButton br = new JButton("resume");
public TNotify(Container c, TText t) {
this.t = t;
br.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
StartT();
}
});
c.add(br);
start();
}
public void StartT() {
startf = true;
}
public void run() {
while (true) {
if (startf) {
t.resume();
startf = !startf;
}
try {
sleep(100);
}
catch (InterruptedException e) {
System.err.println("Interrupted");
}
}
}
}

public class ThreadT
extends JFrame {
private JButton
bs = new JButton("start"),
bp = new JButton("pause"),
br = new JButton("resume");
private JPanel p = new JPanel();
private TText t;
private TNotify tn;
public ThreadT() throws HeadlessException {
super("Test");
this.setSize(300, 200);
Container cp = getContentPane();
cp.setLayout(new FlowLayout());
t = new TText(cp);
bs.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
t.StartT();
}
});
cp.add(bs);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

}

public static void main(String[] args) throws HeadlessException {
ThreadT threadT1 = new ThreadT();
}

}
mooninsun 2005-07-31
  • 打赏
  • 举报
回复
的确java2不赞成使用suspend()和resume()方法
因为他们容易造成死锁,不过可以在synchronized函数中调用wait()和notify()
就不会产生异常IllegalMonitorStateException
呵呵,不过是理论的东东,我操作起来不熟,所以还是使用suspend()和resume()方法
cozmic (蓝色的猪) :
我把你的程序改成了这样:
import java.util.*;

class CanPause
extends Thread {
// 从0累加到10000
private int counter = 0;
public void run() {
while (counter < 10000) {
System.out.print(counter++ +" ");
try {
sleep(100);
}catch(InterruptedException e) {
System.err.println("Interrupted");
}
}
}
}

public class Pausing {
public static void main(String[] args) {
final CanPause pauseable = new CanPause();
pauseable.start();
//100ms 后,暂停程序执行
new Timer(true).schedule(new TimerTask() {
public void run() {
System.out.println("start waiting----------------\n");
pauseable.suspend();
}
}, 100);
// 2500ms后,恢复执行
new Timer(true).schedule(new TimerTask() {
public void run() {
System.out.println("start notifying--------------\n");
pauseable.resume();
}
}, 2500);
}
}
运行没问题的
vootoss 2005-07-31
  • 打赏
  • 举报
回复
我认为应该使用
java.util.timer.*
中的类来控制thread的行为。
这个类就是用来控制代码定时启动的。给你一点我的代码,希望对你有所帮助。
/*
restime就是你所需要的间隔时间,这个方法一旦被调用,将在restime/1000秒之后执行run()中的代码,你只需要很少的工作就可以使他重复的执行。还是一句话,多看看api
*/
public void AllStart() {
timer.schedule(new TimerTask() {
public void run() {

//dosomething

}
}, restime);
System.out.println("下次运行在"+(restime/1000)+"秒后");
}
mooninsun 2005-07-31
  • 打赏
  • 举报
回复
你可以看出产生了IllegalMonitorStateException的异常
这说明对于pauseable.wait()并没有synchronized也就是上锁
所以pauseable.wait()并没有起任何作用,后面的notifyALl()就更不用说了
我帮你改成了下面的程序,你看看:
import java.util.*;

class CanPause
extends Thread {
// 从0累加到10000
private int counter = 0;
public boolean pf = false;
public synchronized void run() { //注意这里用了synchronized,因为要调用wait()
while (counter < 10000) {
System.out.print(counter++ +" ");
try {
sleep(100);
if(pf) {
wait();
pf = !pf;
}
}catch(InterruptedException e) {
System.err.println("Interrupted");
}
}
}
}

public class Pausing {
public static void main(String[] args) {
final CanPause pauseable = new CanPause();
pauseable.start();
//100ms 后,暂停程序执行
new Timer(true).schedule(new TimerTask() {
public void run() {
System.out.println("start waiting----------------\n");
pauseable.pf = true;
}
}, 100);
// 2500ms后,恢复执行
new Timer(true).schedule(new TimerTask() {
public void run() {
System.out.println("start notifying--------------\n");
synchronized (pauseable) { //这里我把CanPause.class改成了pauseable
pauseable.notify();
}
}
}, 2500);
}
}
ffgg 2005-07-31
  • 打赏
  • 举报
回复
# synchronized(CanPause.class) {
# try {
# pauseable.wait();
~~~~~~~~~~~~~~~wait和notify方法只能由current thread调用,这个地方必然产生异常IllegalMonitorStateException
# } catch(Exception e ){} //怎么没把异常打印出来 :)
# }

如果需要由外部暂停线程,并不赞同使用suspend()方法!可以通过设置标记;时间的精度控制很困难 :)
yangbc 2005-07-31
  • 打赏
  • 举报
回复
不可能精确暂停时间
smlovetp 2005-07-30
  • 打赏
  • 举报
回复
我疏忽了~~
不过我运行了几便都出效果啊~~
还是你们强啊
mooninsun 2005-07-30
  • 打赏
  • 举报
回复
假如线程t1在下载
那么button pause addactionlistener完成t1.wait();
在button resume 的addactionlistener完成t1.notify();
believefym 2005-07-30
  • 打赏
  • 举报
回复
楼主的问题应该就是一个线程的sleep和唤醒问题,不是程序暂停问题吧
加载更多回复(14)

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧