`
yxsylyh
  • 浏览: 31984 次
  • 性别: Icon_minigender_1
  • 来自: 哈尔滨
社区版块
存档分类
最新评论

多线程编程的一个例子

    博客分类:
  • JAVA
阅读更多

关于多线程,理解上不难,做出来真不容易。

 

作业题是这样的:做三个线程(A、B、C),启动后输出启动信息,然后A、B调用wait等待;线程C调用sleep休眠一段时间,然后调用notifyAll,使线程A和线程B继续运行。线程A和线程B恢复运行后输出结束信息后结束,线程C判断线程A和B结束后,C自己也结束。

 

最初做的时候,抛出异常,网上查找,才知道多线程的代码要放到synchronized块里面。OK!照做,可还是出错,没有被唤醒。仔细看多线程说明,是需要一个共同的数据作为等待和唤醒的共享资源。费劲周折,使用Boolean值吧,可还是不唤醒,即使加了static也不行。

 

最后在一篇博文里看到只用布尔值还不行,得用数组,于是把布尔值改为布尔数组,问题最终得到解决。

 

最终代码是这样:

package thread;

/**
 * 
 * 线程类
 * 
 * 功能: 如果标志 isManager 是 False,则该线程是普通线程(A和B线程),线程开始并输出信息后进入等待状态;<br>
 * 如果标志 isManager 是 True,则该线程是管理线程(C线程),线程开始、输出信息并休眠一段时间(1秒)后唤醒其它线程。<br>
 * 
 * status 是线程唤醒条件,为 false 的话,则普通线程要一直等待下去;<br>
 * 管理线程设置其值为 true ,并唤醒其它线程。
 * 
 */
public class ThreadABC extends Thread {

	String threadName = "";
	Boolean isManager = Boolean.FALSE;
	static Boolean[] status = { false };
	int time = 1000; // 休眠时长

	/**
	 * 构造函数
	 */
	public ThreadABC() {
	}

	/**
	 * 构造函数
	 * 
	 * @param threadName
	 *            线程名称
	 * @param isManager
	 *            线程标志(false 为普通线程,true 为管理线程)
	 * @param status
	 *            线程唤醒条件(也许不需要从外部赋值?)
	 */
	public ThreadABC(String threadName, Boolean isManager, Boolean[] status) {
		this.threadName = threadName;
		this.isManager = isManager;
		this.status = status;
	}

	public Boolean[] getStatus() {
		return status;
	}

	public void setStatus(Boolean[] status) {
		this.status = status;
	}

	public void run() {
		System.out.println(threadName + " 线程已经启动!");
		// 如果不是管理线程,则进入等待状态
		if (!isManager) {
			// 如果满足等待条件(是 false)
			while (!status[0])
				synchronized (status) {
					// synchronized (this) {
					try {
						System.out.println(threadName + " 开始等待");
						status.wait();
						// this.wait();
						System.out.println(threadName + " 已被唤醒");
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
		} else {
			// 是管理线程,负责改变条件,并通知其它线程
			System.out.println(threadName + " 休眠" + time / 1000 + "秒");
			try {
				sleep(time);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			// Boolean[] status = { true };
			// this.setStatus(status);
			status[0] = true;
			System.out.println(threadName + " 正在唤醒其它线程");
			synchronized (status) {
				// synchronized (this) {
				status.notifyAll();
				// this.notifyAll();
			}
		}
		System.out.println(threadName + " 线程结束!");
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		// main 函数放到其它的类里也能成功
		// 不成功的原因是只使用布尔值不行,
		// 需要把布尔值放到一个数组里就成了
		Boolean[] status = { false };
		ThreadABC threadA = new ThreadABC("Thread A", Boolean.FALSE, status);
		ThreadABC threadB = new ThreadABC("Thread B", Boolean.FALSE, status);
		ThreadABC threadC = new ThreadABC("Thread C", Boolean.TRUE, status);
		threadA.start();
		threadB.start();
		threadC.start();
	}
}

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics