JAVA范例 十三)多线程编程(2)
13.3 线程的优先级
实例238 排座位(线程优先级)
package Chapter17;import java.util.*;public class ThreadPriority {public static void main(String[] args) { // java程序主入口处List list = new ArrayList();// 创建一个List对象Student stu1 = new Student("张三", 5, 98, 130);// 创建一个Student对象list.add(stu1);// 将Student对象添加到List列表中Student stu2 = new Student("李国", 3, 95, 150);list.add(stu2);Student stu3 = new Student("聂亮", 4, 100, 120);list.add(stu3);Student stu4 = new Student("欧阳雪", 6, 91, 140);list.add(stu4);Student stu5 = new Student("肖肖", 7, 93, 150);list.add(stu5);System.out.println("按成绩分数的高低排坐");new Score().RowSeat(list);System.out.println("按个子的高低排坐");new Height().RowSeat(list);}}class Height implements Runnable { // 线程实现接口RunnableThread thread; // 声明一个线程Height() {} // 默认构造方法Height(String name) { // 构造方法初始一个线程thread = new Thread(this, name);}public void run() {System.out.println("一年一班的学生成员:" + thread.getName()); // 获得线程的名称}public void RowSeat(List list) { // 按优先级执行线程Student st = (Student) list.get(0);Student st1 = (Student) list.get(1);Student st2 = (Student) list.get(2);Student st3 = (Student) list.get(3);Student st4 = (Student) list.get(4);Height o1 = new Height(st.name);// 创建线程对象并命名Height o2 = new Height(st1.name);Height o3 = new Height(st2.name);Height o4 = new Height(st3.name);Height o5 = new Height(st4.name);o1.thread.setPriority(st.height / 10 - 10); // MAX_PRIORITY优先级最大o2.thread.setPriority(st1.height / 10 - 10); // 较次之o3.thread.setPriority(st2.height / 10 - 10); // NORM_PRIORITY处于中间位置o4.thread.setPriority(st3.height / 10 - 10);o5.thread.setPriority(st4.height / 10 - 10); // MIN_PRIORITY优先级最小o1.thread.start(); // 启动线程o2.thread.start();o3.thread.start();o4.thread.start();o5.thread.start();try {o5.thread.join(); // 等待线程运行结束} catch (InterruptedException e) { // 捕获拦截异常System.out.println("等待线程结束出错:" + e.getMessage());}}}class Score extends Thread {Thread thread;public Score() {} // 默认构造方法public Score(String name) { // 带参数构造方法初始一个线程thread = new Thread(this, name);}public void run() {System.out.println("一年一班的学生成员:" + thread.getName()); // 获得线程的名称}public void RowSeat(List list) { // 按优先级执行线程Student st = (Student) list.get(0);Student st1 = (Student) list.get(1);Student st2 = (Student) list.get(2);Student st3 = (Student) list.get(3);Student st4 = (Student) list.get(4);Score e1 = new Score(st.name);// 创建线程对象并命名Score e2 = new Score(st1.name);Score e3 = new Score(st2.name);Score e4 = new Score(st3.name);Score e5 = new Score(st4.name);e1.thread.setPriority(st.score / 10); // MAX_PRIORITY优先级最大e2.thread.setPriority(st1.score / 10); // 较次之e3.thread.setPriority(st2.score / 10); // NORM_PRIORITY处于中间位置e4.thread.setPriority(st3.score / 10);e5.thread.setPriority(st4.score / 10); // MIN_PRIORITY优先级最小e1.thread.start(); // 启动线程e2.thread.start();e3.thread.start();e4.thread.start();e5.thread.start();try {e5.thread.join(); // 等待线程运行结束} catch (InterruptedException e) { // 捕获拦截异常System.out.println("等待线程结束出错:" + e.getMessage());}}}class Student {// 学生类public String name;// 姓名public int age;// 年龄public int score;// 成绩public int height;// 身高public Student(String name, int age, int score, int height) {// 构造函数为各成员变量this.name = name;this.age = age;this.height = height;this.score = score;}}?
实例239 赛车
package Chapter17.status;import java.awt.BorderLayout;import java.awt.Dimension;import java.awt.event.ActionEvent;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JProgressBar;import javax.swing.SwingConstants;public class Nascar extends JFrame {private JPanel panel;// 声明布局格式private BorderLayout borderLayout1 = new BorderLayout();private JLabel label = new JLabel();// 创建JProgressBar对象并实例化private JProgressBar bar_1 = new JProgressBar();private JProgressBar bar_2 = new JProgressBar();private JButton button_1 = new JButton();// 创建Priority类对象并实例化private Priority thread_1 = new Priority(bar_1, 10);private Priority thread_2 = new Priority(bar_2, 5);private void Initial() throws Exception {// 创建初始化程序,为其成员变量赋初值panel = (JPanel) this.getContentPane();label.setFont(new java.awt.Font("Dialog", 0, 14));label.setToolTipText("");label.setHorizontalAlignment(SwingConstants.CENTER);label.setText("赛车-线程的优先级(右边的优先级>左边的优先级)");panel.setLayout(borderLayout1);this.setSize(new Dimension(333, 232));this.setTitle("赛车比赛");bar_1.setOrientation(JProgressBar.VERTICAL);// 设置进度条的垂直方式bar_1.setFont(new java.awt.Font("Dialog", 0, 14));// 设置进度条上显示字体的大小bar_1.setMaximumSize(new Dimension(84, 32764));// 设置该进度条的最大值bar_1.setPreferredSize(new Dimension(126, 148));// 设置此组件的首选大小bar_1.setString("1号参赛者");// 给进度条设置显示文字bar_1.setStringPainted(true);bar_2.setOrientation(JProgressBar.VERTICAL);bar_2.setFont(new java.awt.Font("Dialog", 0, 14));bar_2.setPreferredSize(new Dimension(126, 148));bar_2.setString("2号参赛者");bar_2.setStringPainted(true);button_1.setFont(new java.awt.Font("Dialog", 0, 14));button_1.setToolTipText("");button_1.setText("开始");setSize(500, 500);setVisible(true);button_1.addActionListener(new java.awt.event.ActionListener() {public void actionPerformed(ActionEvent e) {AddEvent(e);}});panel.add(label, BorderLayout.NORTH);panel.add(bar_1, BorderLayout.WEST);panel.add(bar_2, BorderLayout.EAST);panel.add(button_1, BorderLayout.SOUTH);}void AddEvent(ActionEvent e) {// 为按扭添加事件监听if (((JButton) e.getSource()).getText().equals("开始")) {// 当单击按钮文字是"Start",则单击后设为"stop",并且创建两个Priority的实例,但这两个线程的优先级不同,然后才可以运行线程。this.button_1.setText("停止");Priority thread_1 = new Priority(this.bar_1, Thread.MAX_PRIORITY);thread_1.start();Priority thread_2 = new Priority(this.bar_2, Thread.MIN_PRIORITY);thread_2.start();} else {this.button_1.setText("开始");this.thread_1.stopped = true;}}public static void main(String[] args) {// 该程序的入口处try {new Nascar().Initial();// 调用该程序的Initial方法} catch (Exception e) {e.printStackTrace();}}}class Priority extends Thread {// 设置线程优先级的类JProgressBar bar_3;// 声明一个进度条对象static boolean stopped;// 声明一个是否停止的标识public Priority(JProgressBar bar_3, int priority) {// 构造方法为成员变量赋初值this.bar_3 = bar_3;this.stopped = false;this.setPriority(priority);}public void run() {// 启动线程int min = 0;int max = 1000;this.bar_3.setMinimum(min);this.bar_3.setMaximum(max / 10);this.bar_3.setValue(min);for (int i = min; i <= max; i++) {if (stopped) {break;} else {this.bar_3.setValue((int) (i / 10));this.bar_3.setString(String.valueOf(i));try {Thread.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}}}}}?
13.4 定时器
实例240 定时器(Timer)
package Chapter17.status;import java.util.Date;import java.util.Timer;import java.util.TimerTask;public class TimerThread {public static void main(String[] args) { // java程序主入口处Timer timer = new Timer(); // 创建定时器类TimerTask tt1 = new MyTask(1);timer.schedule(tt1, 200); // 0.2秒后执行任务TimerTask tt2 = new MyTask(2);timer.schedule(tt2, 500, 1000); // 0.5秒后执行任务并每个1秒执行一次TimerTask tt3 = new MyTask(3);Date date = new Date(System.currentTimeMillis() + 1000);timer.schedule(tt3, date); // 在指定时间1秒后执行任务try {Thread.sleep(3000); // 休眠3秒钟} catch (InterruptedException e) { // 捕获拦截异常System.out.println("出现错误:" + e.getMessage());}timer.cancel(); // 终止定时器取消定时器中的任务System.out.println("任务定时器已经被取消");}}class MyTask extends TimerTask { // 继承时间任务类执行任务private int taskID = 0; // 任务编号public MyTask(int id) { // 带参数的构造方法进行初始化this.taskID = id;}public void run() { // 实现TimerTask中的方法System.out.println("开始执行我的第" + this.taskID + "个任务 ,执行时间为"+ new Date().toLocaleString());}}?
实例241 数字定时器
import java.awt.Color;import java.awt.FlowLayout;import java.awt.Font;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.lang.reflect.InvocationTargetException;import java.text.DecimalFormat;import javax.swing.BorderFactory;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.SwingConstants;import javax.swing.SwingUtilities;public class DigitalTimer extends JLabel implements ActionListener {// 数字计时器private volatile String value;// 要在文本框中显示的内容private Thread thread;// 声明一个线程private volatile boolean isStop;// 标识是否停止计时Runnable r = null;//声明一个Runnable子类的对象public DigitalTimer() {// 构造方法为Swing组件初始化setBorder(BorderFactory.createLineBorder(Color.blue));setHorizontalAlignment(SwingConstants.RIGHT);this.setForeground(Color.red);setFont(new Font("SansSerif", Font.BOLD, 16));setText("00000.0"); // use to size componentsetMinimumSize(getPreferredSize());setPreferredSize(getPreferredSize());setSize(getPreferredSize());value = "0.0";setText(value);isStop = true;r = new Runnable() {// 创建一个实现Runnable接口内部类对象public void run() {try {startTime();} catch (Exception x) {x.printStackTrace();}}};thread = new Thread(r, "Stopwatch");// 根据Runnable对象来创建一个线程thread.start();// 启动线程}private void startTime() {// 开始计时long startTime = System.currentTimeMillis();// 线程开始运行的时间int n = 0;// 一个时间量long sleepTime = 100;// 线程正在休眠的时间long nextSleepTime = 100;// 接下来准备休眠的时间DecimalFormat format = new DecimalFormat("0.0");Runnable updateText = new Runnable() {public void run() {setText(value);}};while (isStop) {try {Thread.sleep(nextSleepTime);n++;long nowTime = System.currentTimeMillis();// 获取系统的当前时间long elapsedTime = nowTime - startTime;// 经过的时间=当前时间-开始时间nextSleepTime = sleepTime + ((n * 100) - elapsedTime);if (nextSleepTime < 0) {nextSleepTime = 0;}value = format.format(elapsedTime / 1000.0);System.out.println(value);SwingUtilities.invokeAndWait(updateText);// 使该线程在Swing组件上同步执行} catch (InterruptedException ix) {return;// 停止运行} catch (InvocationTargetException x) {x.printStackTrace();}}}public void endTime() {// 结束计时isStop = false;thread.interrupt();// 中断线程}public boolean isAlive() {return thread.isAlive();// 判断该线程是否是活动的}public static void main(String[] args) {DigitalTimer dt = new DigitalTimer();// 创建一个本类的实例化对象JPanel p = new JPanel(new FlowLayout());// 创建一个面板对象,其布局方式为流布局p.add(dt);// 将类对象添加到面板中JFrame frame = new JFrame("数字计时器");// 创建一个框架// 创建2个JButton按扭,其作用是开始计时和停止计时。并为其添加相应的事件处理JButton b1 = new JButton();b1.setText("开始");// 为接扭设置文本文字b1.setBounds(20, 40, 60, 20);// 设置按扭的大小b1.setActionCommand("start");// 设置激发此按扭的事件命令名称b1.addActionListener(dt);// 添加监听事件JButton b2 = new JButton();b2.setText("停止");b2.setBounds(80, 40, 60, 20);b2.setActionCommand("end");// 设置激发此按扭的事件命令名称b2.addActionListener(dt);// 添加监听事件frame.setContentPane(p);// 在该框架中添加面板frame.add(b1);// 在该框架中添加按扭组件frame.add(b2);frame.setSize(250, 100);// 设置框架的大小frame.setVisible(true);// 设置框架为可见}public void actionPerformed(ActionEvent e) {// 事件处理if (e.getActionCommand().equals("start")) {// 如果激发开始按扭if (!isAlive()) {// 判断如果当前的线程不处于可活动状态isStop = true;// 将状态设置为truethread = new Thread(r, "Stopwatch");// 重新根据Runnable对象来创建一个新的线程thread.start();// 启动新线程} else {startTime();}} else if (e.getActionCommand().equals("end")) {// 如果激发停止按扭endTime();// 则调用endTime方法,中断当前正在运行的线程}}}?
13.5 线程连接池
实例242 手术任务(线程池)
package Chapter17;import java.util.*;public class SurgeryThreadPool {private static Runnable createTask(final int taskID) { // 创建任务方法return new Runnable() {public void run() { // 创建手术任务System.out.println("手术开始,编号为" + taskID);System.out.println("正在手术中~~");System.out.println("手术结束,编号为" + taskID);}};}public static void main(String[] args) { // java程序主入口处ThreadTask threadPool = new ThreadTask(3); // 创建一个有个3任务线程的线程池try {// 休眠600毫秒,让线程池中的任务线程全部运行Thread.sleep(600);} catch (InterruptedException e) { // 捕获拦截异常System.out.println("线程休眠出错:" + e.getMessage());}for (int i = 0; i < 3; i++) { // 循环创建并执行任务threadPool.addTask(createTask(i));}threadPool.waitTaskColsed(); // 等待所有任务执行完毕threadPool.closePool(); // 关闭线程池}}class ThreadTask extends ThreadGroup { // 继承线程组实现线程池功能private boolean isStop = false; // 线程池是否关闭private LinkedList queue; // 工作任务队列private static int poolID = 1; // 线程池的编号private class SurgeryTask extends Thread { // 负责从工作队列中取出任务并执行的内部类private int id; // 任务编号public SurgeryTask(int id) { // 构造方法进行初始化super(ThreadTask.this, id + ""); // 将线程加入到当前线程组中this.id = id;}public void run() {while (!isInterrupted()) { // 判断线程是否被中断Runnable task = null;task = getTask(id); // 取出任务// 如果getTask()返回null或者线程执行getTask()时被中断,则结束此线程if (task == null)return;try {task.run(); // 运行任务} catch (Throwable t) {t.printStackTrace();}}}}public ThreadTask(int size) { // 构造方法传入线程池中的工作线程的数量super(poolID + ""); // 指定线程组名称setDaemon(true); // 继承线程组的方法用来设置是否守护线程池queue = new LinkedList(); // 创建工作任务队列for (int i = 0; i < size; i++) { // 循环创建任务线程new SurgeryTask(i).start(); // 根据线程池数据创建任务线程并启动线程,}}public synchronized void addTask(Runnable task) {// 添加新任务并执行任务if (isStop) { // 判断标识throw new IllegalStateException(); // 抛出不合理状态异常}if (task != null) {queue.add(task); // 向任务队列中加入一个任务notify(); // 唤醒待任务的工作任务线程}}private synchronized Runnable getTask(int id) { // 取出任务try {while (queue.size() == 0) { // 循环使线程等待任务if (isStop)return null;System.out.println("病人" + id + "正在等待手术...");wait(); // 如果任务队列中没有任务,就等待任务}} catch (InterruptedException e) { // 捕获拦截异常System.out.println("等待治疗出现错误:" + e.getMessage());}System.out.println("病人" + id + "开始执行手术...");return (Runnable) queue.removeFirst();// 返回第一个任务并从队列中删除}public synchronized void closePool() { // 关闭线程池if (!isStop) { // 判断标识waitTaskColsed(); // 等待任务线程执行完毕isStop = true; // 标识为真queue.clear(); // 任务队列清空interrupt(); // 唤醒线程池中的所有的工作线程}}public void waitTaskColsed() { // 等待任务线程把所有任务执行完毕synchronized (this) {isStop = true; // 标识为真notifyAll(); // 唤醒待任务的工作任务线程}Thread[] threads = new Thread[activeCount()];// 创建线程组中活动的线程组int count = enumerate(threads); // 获得线程组中当前所有活动的工作线程for (int i = 0; i < count; i++) { // 循环等待所有工作线程结束try {threads[i].join(); // 等待工作线程结束} catch (InterruptedException e) { // 捕获拦截异常System.out.println("手术失败:" + e.getMessage());}}}}?
实例243 模拟人工服务台(线程连接池)
public class CallCenter extends Object {//客服中心private static int nextServiceID = 0;//下一个客服的IDprivate InterNIC iNIC;//声明网际网络信息中心对象private int ServiceID;//客服IDprivate InterNIC handoffBox;//声明网际网络信息中心对象private Thread thread;//声明一个线程对象private volatile boolean isStop;//停止服务的标志public CallCenter(InterNIC iNIC) {//构造函数this.iNIC = iNIC;ServiceID = getNextWorkerID();handoffBox = new InterNIC(1); isStop = true;Runnable r = new Runnable() {public void run() {try {runWork();} catch ( Exception x ) {x.printStackTrace(); }}};thread = new Thread(r);thread.start();}public static synchronized int getNextWorkerID() { //获取下个客服ID号int id = nextServiceID;nextServiceID++;return id;}public void process(Runnable target) throws InterruptedException {handoffBox.add(target);}private void runWork() {//正在工作中while ( isStop ) {try {System.out.println("客服" + (ServiceID+1) + "号, 正在通话中,请稍候…");iNIC.add(this);Runnable r = (Runnable) handoffBox.remove();System.out.println("客服" + (ServiceID+1) + "号, 正在与另一位新用户" + r+"建立通话连接…");runFailed(r); } catch ( InterruptedException x ) {Thread.currentThread().interrupt(); }}}private void runFailed(Runnable r) {//连接失败try {r.run();} catch ( Exception runex ) {System.err.println("连接失败,暂时无法接通…");runex.printStackTrace();} finally {Thread.interrupted();}}public void stopRequest() {//停止服务System.out.println("客服" + (ServiceID+1)+ "号, 停止服务");isStop = false;thread.interrupt();}public boolean isAlive() {return thread.isAlive();//判断该线程是否处于活动状态}}?
public class InterNIC extends Object {private Object[] queue;// 声明一个队列private int capacity;// 信息容量private int size;// 大小private int head;// 信息头private int tail;// 信息尾public InterNIC(int cap) {capacity = (cap > 0) ? cap : 1; // 设初始容量为1queue = new Object[capacity];// 根据容量创建一个Object数组head = 0;tail = 0;size = 0;}public int getCapacity() {// 获取容量return capacity;}public synchronized int getSize() {// 获取信息的大小return size;}public synchronized boolean isEmpty() {// 判断信息是否空return (size == 0);}public synchronized boolean isFull() {// 判断信息是否return (size == capacity);}public synchronized void add(Object obj) throws InterruptedException {//添加信息waitWhileFull();queue[head] = obj;head = (head + 1) % capacity;size++;notifyAll();}public synchronized void addEach(Object[] list) throws InterruptedException {//添加信息尾部for (int i = 0; i < list.length; i++) {add(list[i]);}}public synchronized Object remove() throws InterruptedException {//信息的移出waitWhileEmpty();Object obj = queue[tail];queue[tail] = null;tail = (tail + 1) % capacity;size--;notifyAll();return obj;}public synchronized Object[] removeAll() throws InterruptedException {//信息全部移出Object[] list = new Object[size]; // use the current sizefor (int i = 0; i < list.length; i++) {list[i] = remove();}return list;}public synchronized Object[] removeAtLeastOne() throws InterruptedException {waitWhileEmpty();return removeAll();}public synchronized boolean waitUntilEmpty(long msTimeout)//逐渐将信息全部清除throws InterruptedException {if (msTimeout == 0L) {waitUntilEmpty();return true;}long endTime = System.currentTimeMillis() + msTimeout;long msRemaining = msTimeout;while (!isEmpty() && (msRemaining > 0L)) {wait(msRemaining);msRemaining = endTime - System.currentTimeMillis();}return isEmpty();}public synchronized void waitUntilEmpty() throws InterruptedException {while (!isEmpty()) {wait();}}public synchronized void waitWhileEmpty() throws InterruptedException {while (isEmpty()) {wait();}}public synchronized void waitUntilFull() throws InterruptedException {while (!isFull()) {wait();}}public synchronized void waitWhileFull() throws InterruptedException {while (isFull()) {wait();}}}?
?
public class TelephoneLine extends Object {private InterNIC iNIC;// 声明网际网络信息中心对象private CallCenter[] serviceList;// 创建一个客服对象数组public TelephoneLine(int numOfLine) {// 构造方法,其中numOfLine表示线路的个数numOfLine = Math.max(1, numOfLine);iNIC = new InterNIC(numOfLine);serviceList = new CallCenter[numOfLine];for (int i = 0; i < serviceList.length; i++) {serviceList[i] = new CallCenter(iNIC);}}public void execute(Runnable target) throws InterruptedException {// 执行任务CallCenter Service = (CallCenter) iNIC.remove();Service.process(target);}public void StopServiceOfID() {// 某个ID的客服停止服务try {Object[] idle = iNIC.removeAll();for (int i = 0; i < idle.length; i++) {((CallCenter) idle[i]).stopRequest();}} catch (InterruptedException x) {Thread.currentThread().interrupt();}}public void StopServiceAll() {// 全部客服停止服务StopServiceOfID();try {Thread.sleep(250);} catch (InterruptedException x) {}for (int i = 0; i < serviceList.length; i++) {if (serviceList[i].isAlive()) {serviceList[i].stopRequest();}}}}?
public class TelephoneOffice extends Object {public static Runnable makeRunnable(final String name, final long firstDelay) {return new Runnable() {public void run() {try {System.out.println(name +": 请求拨号,正在连接中…");Thread.sleep(firstDelay);System.out.println(name + ": 正在通话中…");Thread.sleep(2000);System.out.println(name + ": 通语结束");} catch ( InterruptedException ix ) {System.out.println(name + ": 网络异常");return;} catch ( Exception x ) {x.printStackTrace();}}public String toString() {return name;}};}public static void main(String[] args) {try {TelephoneLine pool = new TelephoneLine(3);Runnable zs = makeRunnable("张三", 3000);pool.execute(zs);Runnable ls = makeRunnable("李四", 1000);pool.execute(ls);Runnable nql = makeRunnable("聂庆亮", 2000);pool.execute(nql);Runnable zxh = makeRunnable("张小红", 60000);pool.execute(zxh);Runnable yjp = makeRunnable("尹继平", 1000);pool.execute(yjp);pool.StopServiceOfID();Thread.sleep(2000);pool.StopServiceOfID();Thread.sleep(5000);pool.StopServiceAll();} catch ( InterruptedException ix ) {ix.printStackTrace();}}}?
?