如何让一个线程中的函数暂停执行?

zhengkai2001 2014-04-04 09:24:46

A类继承Thread,B类中包含A类的实例a,同时通过两个按钮来控制a中的线程的暂停执行与恢复执行,下面是代码示意:


public class A extends Thread {
@Override
public void run() {
process();
}

private void process() {
/*......*/
}
}

public class B {
A a;

private void function() {
//......
JButton button_start = new JButton("开始");
button_start.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
a = new A();
a.start();
}
});

JButton button_pause = new JButton("暂停");
button_pause.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// 在这里让线程a暂停
}
});

JButton button_resume = new JButton("恢复");
button_resume.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// 在这里让线程a继续
}
});
//......
}
}



在不改变process()函数体的情况下,这个暂停和继续能够实现吗?
...全文
321 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
nmyangym 2014-04-10
  • 打赏
  • 举报
回复
利用wait() notify() 写了一个。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

class ThreadClass extends JTextField implements Runnable {
	//--- flag 控制线程状态 ---
	private boolean flag = true;
	public boolean isFlag() {
		return flag;
	}

	public void setFlag(boolean flag) {
		this.flag = flag;
	}
	
	//--- 通过累计计数模拟线程运行---
	int times = 0;

	//--- 设置文本框主要是显示线程状态 ---
	public ThreadClass(String s) {
		super(s);
		setBackground(Color.ORANGE);//---橘黄
		setEditable(false);
		setHorizontalAlignment(JTextField.CENTER);
	}

	
	@Override
	public void run() {
		process();
	}

	private synchronized void process() {
		while (true) {//无限循环

			if (flag == true) {
				this.setText("This is the " + (times++)
						+ "th times running \n");
				try {
					Thread.sleep(100);
				} catch (InterruptedException ie) {
					ie.printStackTrace();
				}
				notify();//--- 唤醒另一线程 --- ,本代码其实没有其他等待线程,这个可不用 ---
			} else {
				this.setText(" When times = " + times + "\n The thread is paused!");
				try {
					wait();//--- 进入等待
				} catch (InterruptedException ie) {
					ie.printStackTrace();
				}
			}
		}
	}

}

public class ThreadControll extends JFrame {
	ThreadClass a = new ThreadClass("请按开始按钮!");
	Thread startThread = null;
	public ThreadControll(String s) {
		super(s);
		final Container c = getContentPane();
		c.setLayout(new BorderLayout());

		JPanel jp = new JPanel(new FlowLayout());
		JButton button_start = new JButton("开始");
		JButton button_pause = new JButton("暂停");
		JButton button_resume = new JButton("恢复");

		jp.add(button_start);
		jp.add(button_pause);
		jp.add(button_resume);

		//--- 开始按钮只执行一次 ---
		button_start.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent ae) {
				if (null == startThread) {
					startThread =  new Thread(a);
					startThread.start();
				}
			}
		});
		
		//--- 暂停按钮 ,按下后如果没有按继续,就不改变标志 ---
		button_pause.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (a.isFlag() != false) {
					a.setFlag(false);
				}
			}
		});

		//--- 恢复按钮,这个最关键,主要是用notify()让线程继续执行,---
		button_resume.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				if (a.isFlag() == false) {
					
					a.setFlag(true);
					synchronized (a) {//--- 如果不放在同步快里,无法实现唤醒 ---
						a.notify();//--- 这个代码执行完后,a对象锁就释放了 所以process() 方法里德 notify()可不用---
					}
				}
			}
		});
		c.add(jp,BorderLayout.NORTH);
		c.add(a, BorderLayout.CENTER);
	}
	
	//--- 入口 ---
	public static void main(String[] args) {
		ThreadControll tc = new ThreadControll("test");
		tc.setSize(400, 200);
		tc.setVisible(true);
		tc.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
}
zhengkai2001 2014-04-08
  • 打赏
  • 举报
回复
自己顶顶,长度补丁
zhengkai2001 2014-04-04
  • 打赏
  • 举报
回复
我是觉得,既然被弃用了,那就应该可以用别的办法完成相同的任务的。。。
zhengkai2001 2014-04-04
  • 打赏
  • 举报
回复
引用 3 楼 benma378 的回复:
亲,我之所以把文档贴上来是让你看下文档对弃用理由的说明 你没有认真看吧 请查看文档,没试验过就没话语权
《Java核心技术》和文档我都看了 我想知道别的方法
俺是小王子 2014-04-04
  • 打赏
  • 举报
回复
亲,我之所以把文档贴上来是让你看下文档对弃用理由的说明 你没有认真看吧 请查看文档,没试验过就没话语权
zhengkai2001 2014-04-04
  • 打赏
  • 举报
回复
引用 1 楼 benma378 的回复:
我没在我机器上实验过哈,提出小小的想法 A是线程的子类 直接调用线程的suspend()方法行不行?在调用前线判断该线程状态,下一个问题同样如此,调用resume方法恢复
恩。。。可是如你所说,这几个方法已经被弃用了,我想知道有没有别的好一点的方法
俺是小王子 2014-04-04
  • 打赏
  • 举报
回复
我没在我机器上实验过哈,提出小小的想法 A是线程的子类 直接调用线程的suspend()方法行不行?在调用前线判断该线程状态,下一个问题同样如此,调用resume方法恢复 具体请参考API文档 关于这些方法在1.7中已经不建议使用
@Deprecated
public final void suspend()

Deprecated. This method has been deprecated, as it is inherently deadlock-prone. If the target thread holds a lock on the monitor protecting a critical system resource when it is suspended, no thread can access this resource until the target thread is resumed. If the thread that would resume the target thread attempts to lock this monitor prior to calling resume, deadlock results. Such deadlocks typically manifest themselves as "frozen" processes. For more information, see Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?.
Suspends this thread.

First, the checkAccess method of this thread is called with no arguments. This may result in throwing a SecurityException (in the current thread).

If the thread is alive, it is suspended and makes no further progress unless and until it is resumed.

Throws:
    SecurityException - if the current thread cannot modify this thread.
See Also:
    checkAccess()
我觉得你的情况可以使用,因为从你的代码来推测,你的没有资源抢占,应该不会造成死锁问题 个人简单想法,仅供参考

50,528

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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