高并发编程:3、实现Runnable接口,来实现多个窗口排队叫号功能

ackage com.cfl.thread;

public class Thread2 {
	private static TestRunnable testRunnable = new TestRunnable();
	// 任务数
	private static LinkedList<String> tasks = new LinkedList<String>();
	// 窗口个数
	private static List<Window> windows = new ArrayList<Window>();
	
	public static void main(String[] args) {
		for(int i = 1; i <= 80; i++) {
			tasks.add(String.valueOf(i));
		}
		Door door = new Door(3);
		// 启动窗口工作
		door.begin();
		
		// 暂停所有窗口
		try {
			Thread.sleep(10*1000);
			System.out.println("======== 暂停所有窗口 ========");
			door.suspendAll();
		} catch (Exception e) {
		}
		
		// 恢复所有暂停窗口
		try {
			Thread.sleep(12*1000);
			System.out.println("======== 恢复所有窗口 ========");
			door.notSuspendAll();
		} catch (Exception e) {
		}
		
		// 暂停某个窗口
		try {
			Thread.sleep(10*1000);
			System.out.println("======== 暂停某个窗口 ========");
			door.suspend(windows.get(1));
		} catch (Exception e) {
		}
		
		// 恢复某个窗口
		try {
			Thread.sleep(12*1000);
			System.out.println("======== 恢复某个窗口 ========");
			door.notSuspend(windows.get(1));
		} catch (Exception e) {
		}
		
		// 减少几个窗口
		try {
			Thread.sleep(20*1000);
			System.out.println("======== 减少窗口 ========");
			door.remove(1);
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
		
		// 减掉所有窗口
		try {
			Thread.sleep(10*1000);
			System.out.println("======== 减掉所有窗口 ========");
			door.removeAll();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		// 增加几个窗口
		try {
			Thread.sleep(20*1000);
			System.out.println("======== 增加窗口 ========");
			door.add(5);
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}
	
	static class Door extends Thread {
		private boolean isActive = true;
		
		/**
		 * 初始化窗口
		 * @param windowSize 窗口数量
		 */
		public Door (int windowSize) {
			for(int i = 0; i< windowSize; i++) {
				Window window = new Window(testRunnable, (windows.size()+1)+"号窗口");
				windows.add(window);
			}
			this.start();
		}
		@Override
		public void run() {
			while (isActive) {
			}
		}
		
		/**
		 * 开始启动窗口
		 */
		public void begin() {
			for(Window window : windows) {
				System.out.println(window.getName()+"开始工作");
				window.start();
			}
		}
		
		/**
		 * 暂停所有
		 */
		public void suspendAll() {
			for(Window window : windows) {
				suspend(window);
			}
		}
		
		/**
		 * 暂停某个窗口
		 * @param window
		 */
		public void suspend(Window window) {
			if(null == window) {
				return;
			}
			if(WindowState.SUSPEND == window.windowState) {
				return;
			}
			window.suspended();
		}
		
		/**
		 * 恢复所有暂停的窗口
		 */
		public void notSuspendAll() {
			for(Window window : windows) {
				window.notSuspended();
			}
		}
		
		/**
		 * 恢复某个窗口
		 * @param window
		 */
		public void notSuspend(Window window) {
			if(null == window) {
				return;
			}
			if(WindowState.SUSPEND != window.windowState) {
				return;
			}
			window.notSuspended();
		}
		
		/**
		 * 删除所有窗口
		 */
		public void removeAll() {
			synchronized(windows) {
				for(Window window : windows) {
					window.shutdown();
				}
			}
		}
		
		/**
		 * 删除几个窗口
		 * @param windowSize
		 */
		public void remove(int windowSize) {
			synchronized (windows) {
				if(windowSize >= windows.size()) {
					removeAll();
				}
				for(int i = windows.size()-1; i >= windows.size()-windowSize; i--) {
					windows.get(i).shutdown();
				}
			}
		}
		
		/**
		 * 添加窗口
		 */
		public void add(int windowSize) throws RuntimeException{
			if(this.isAlive()) {
				synchronized (windows) {
					for(int i = 0; i< windowSize; i++) {
						String name = (windows.size()+1)+"号窗口";
						System.out.println(name+"开始工作");
						Window window = new Window(testRunnable, name);
						window.start();
						windows.add(window);
					}
				}
			} else {
				throw new RuntimeException("门诊还未营业");
			}
		}
	}
	
	private enum WindowState {
		/**
		 * FREE: 空闲
		 * RUNNING:繁忙
		 * SUSPENDING: 暂停中
		 * SUSPEND: 暂停
		 * STOPING:停止中
		 * STOP: 已停止
		 */
		FREE,RUNNING,SUSPENDING,SUSPEND,STOPING,STOP;
	}
	static class Window extends Thread {
		private WindowState windowState;
		public Window(TestRunnable testRunnable, String name) {
			super(testRunnable, name);
			this.windowState = WindowState.FREE;
		}
		public void run() {
			while (true) {
				if(windowState == WindowState.SUSPEND) {
					try {
						Thread.sleep(1*1000);
						continue;
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				if(windowState == WindowState.SUSPENDING) {
					try {
						this.windowState = WindowState.SUSPEND;
						Thread.sleep(1*1000);
						continue;
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				synchronized (tasks) {
					if(tasks.isEmpty()) {
						try {
							System.out.println(Thread.currentThread().getName() + " wait");
							tasks.wait();
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
				super.run();
				try {
					windowState = WindowState.RUNNING;
					int random=(int)(Math.random()*10+1);
					Thread.sleep(random*1000);
					if(windowState == WindowState.RUNNING) {
						windowState = WindowState.FREE;
					}
				} catch (InterruptedException e) {
					if(windowState == WindowState.STOPING) {
						// 停止
						windowState = WindowState.STOP;
						windows.remove(this);
						System.out.println(Thread.currentThread().getName() + ": " + windowState);
						break;
					}
				}
			}
		}
		/**
		 * 停止
		 */
		public void shutdown() {
			this.windowState = WindowState.STOPING;
			this.interrupt();
		}
		/**
		 * 暂停
		 */
		public void suspended() {
			this.windowState = WindowState.SUSPENDING;
			System.out.println(this.getName() + ": " + this.windowState);
		}
		/**
		 * 恢复暂停到执行任务
		 */
		public void notSuspended() {
			if(this.windowState == WindowState.SUSPEND) {
				this.windowState = WindowState.FREE;
			}
		}
	}
	static class TestRunnable implements Runnable {
		public synchronized void run() {
			synchronized (tasks) {
				if(!tasks.isEmpty()) {
					String str = tasks.removeFirst();
					System.out.println(Thread.currentThread().getName() + ": " + str);
					tasks.notifyAll();
				}
			}
		}
	}
}

打印结果:

1号窗口开始工作
2号窗口开始工作
3号窗口开始工作
1号窗口: 1
2号窗口: 2
3号窗口: 3
3号窗口: 4
1号窗口: 5
1号窗口: 6
2号窗口: 7
3号窗口: 8
1号窗口: 9
1号窗口: 10
======== 暂停所有窗口 ========
1号窗口: SUSPEND
2号窗口: SUSPEND
3号窗口: SUSPEND
======== 恢复所有窗口 ========
1号窗口: 11
3号窗口: 12
2号窗口: 13
3号窗口: 14
2号窗口: 15
1号窗口: 16
1号窗口: 17
======== 暂停某个窗口 ========
2号窗口: SUSPEND
3号窗口: 18
3号窗口: 19
1号窗口: 20
1号窗口: 21
3号窗口: 22
======== 恢复某个窗口 ========
2号窗口: 23
1号窗口: 24
2号窗口: 25
3号窗口: 26
2号窗口: 27
1号窗口: 28
3号窗口: 29
2号窗口: 30
======== 减少窗口 ========
3号窗口: STOP
1号窗口: 31
2号窗口: 32
1号窗口: 33
1号窗口: 34
======== 减掉所有窗口 ========
1号窗口: STOP
2号窗口: STOP
======== 增加窗口 ========
1号窗口开始工作
2号窗口开始工作
3号窗口开始工作
1号窗口: 35
4号窗口开始工作
2号窗口: 36
5号窗口开始工作
3号窗口: 37
4号窗口: 38
5号窗口: 39
2号窗口: 40
3号窗口: 41
5号窗口: 42
2号窗口: 43
3号窗口: 44
1号窗口: 45
1号窗口: 46
4号窗口: 47
5号窗口: 48
5号窗口: 49
2号窗口: 50
3号窗口: 51
4号窗口: 52
3号窗口: 53
1号窗口: 54
5号窗口: 55
5号窗口: 56
2号窗口: 57
1号窗口: 58
4号窗口: 59
3号窗口: 60
4号窗口: 61
2号窗口: 62
4号窗口: 63
5号窗口: 64
1号窗口: 65
5号窗口: 66
2号窗口: 67
4号窗口: 68
3号窗口: 69
2号窗口: 70
3号窗口: 71
5号窗口: 72
1号窗口: 73
2号窗口: 74
1号窗口: 75
4号窗口: 76
3号窗口: 77
4号窗口: 78
5号窗口: 79
1号窗口: 80
5号窗口 wait
4号窗口 wait
2号窗口 wait
1号窗口 wait
3号窗口 wait
  • 因为Runnable实现了逻辑和线程分离,所以可以在Runnable中共享一份数据。
  • 因为在Runnable中共享的是同一份数据,所以存在线程安全问题,所以加上了synchronized来控制同步,注意synchronized会导致性能下降。
  • synchronized:修饰对象时表明该对象在任何时候只能由一个线程访问(本案例使用)。
  • synchronized:修饰某一个方法的后,当一个线程A使用这个方法时,其他线程想使用这个方法就必须等待,直到线程A使用完这个方法。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值