Java 线程等待和通报

概要:

wait与notify是Object类而非Thread类的两个操作。这两个操作只能在线程同步的时候有效,并且只能出现在synchronize()方法或者synchronize块中。本实例介绍运用wait与notify模拟实现下载文件并将下载的文件展示出来。

| |目录

技术要点

    运用线程等待和线程通报的技术要点如下:

  • 将显示文件的线程处于等待状态,如果下载线程下载了新的文件,就通报显示线程,显示线程再将文件显示出来。

  • wait方法有两种常用的形式:wait(长整型参数)和wait()。前者是线程等待指定的毫秒数,超过则继续进行,如果参数为0则表示无限等待;wait()方法相当于wait(0),表示无限等待。

  • notify方法也有两种形式:notify()和notifyAll()。notify()方法只通知一个等待该对象的线程,如果有多个,则根据线程调度挑选一个;notifyAll()方法通知所有等待该对象的线程。

代码实现

package net.xsoftlab.baike;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
public class TextWaitAndNotify {// 操作wait()与notify()方法的类
	private static boolean isDone = false;// 标识线程是否停止
	private static List fileList = new ArrayList();// 创建集合列表对象
	private static DateFormat dateFormat = new SimpleDateFormat("HH-mm-ss");
	private class DownLoadFile extends Thread {// 创建模拟下载文件类
		private String[] file = new String[] { "time.txt", "axis.jar",
				"ajax in action.rar", "post.zip" };
		public void run() {// 实现线程类的方法
			for (int i = 0; i < file.length; i++) {
				try {
					int time = new Random().nextInt(100) * 5;// 获得随机生成的秒数
					System.out.println(dateFormat.format(new Date()) + "  下载文件"
							+ file[i] + "用时" + time + " 毫秒. ");
					Thread.sleep(time);// 线程休眠等待
				} catch (Exception e) {// 捕获异常
					System.out.println("下载文件出错:" + e.getMessage());
				}
				synchronized (fileList) {// 实现同步
					System.out.println(dateFormat.format(new Date())
							+ "  下载线程 已下载文件" + file[i]);
					fileList.add(file[i]);// 将文件添加到集合列表中
					fileList.notify();// 通报所有等待的fileList的线程
				}
			}
			isDone = true;// 重新设置标识
			System.out.println(dateFormat.format(new Date()) + "  下载线程 退出");
		}
	}
	private class ShowFile extends Thread {
		public void run() {// 实现线程类的方法
			while (!isDone) {
				synchronized (fileList) {// 实现同步
					try {
						fileList.wait(1000);// 集合列表等待,1秒超时
					} catch (Exception e) {// 捕获异常
						System.out.println("线程等待出现错误:" + e.getMessage());
					}
					while (fileList.size() > 0) {// 如果集合中存在文件
						System.out.println(dateFormat.format(new Date())
								+ "  显示线程 显示文件" + fileList.remove(0));
					}
				}
			}
			System.out.println(dateFormat.format(new Date()) + "  显示线程 退出");
		}
	}
	public static void main(String[] args) {// java程序主入口处
		TextWaitAndNotify text = new TextWaitAndNotify();// 实例化对象
		text.new DownLoadFile().start();// 实例化内部类并启动线程
		text.new ShowFile().start();
	}
}

程序解读

  1. TextWaitAndNotify类的内部类DownLoadFile用于模拟文件下载。其声明一个字符串数组来模拟存储的文件。run()方法根据字符串数组的长度进行循环获得随机生成的下载秒数并输出下载文件的信息,设置线程的休眠时间为随机生成的下载秒数。运用同步方式将字符串文件添加到集合列表中并调用集合列表的notify()方法通报所有等待集合列表的线程。

  2. ShowFile类的run()方法根据标识为真进行循环,对集合列表对象实现同步,其他线程在此时不能操作该集合列表。调用该集合列表的wait()方法,线程会释放集合列表所持有的同步资源(不会释放其他对象的同步锁),这时其他线程可以访问该集合列表。再通过判断集合列表中是否有元素输出文件信息。


评论关闭
评论 还能输入200
评论关闭
评论 还能输入200
  • 全部评论(0)
资料加载中...
已关注 , 取消