需求:

[售票系统】编程模拟三个售票窗口售贾100,分别使用继承 Thread和实现 Runnable方式,并分析有什么问题?

问题:

两种方式均产生了超卖现象。

使用继承 Thread方式创建线程

  1. package test;
  2. /**
  3. * 使用多线程,模拟三个窗口同时售票100张
  4. */
  5. public class Main {
  6. public static void main(String[] args) {
  7. SellTicket01 sellTicket01 = new SellTicket01();
  8. SellTicket01 sellTicket02 = new SellTicket01();
  9. SellTicket01 sellTicket03 = new SellTicket01();
  10. //这里我们会出现超卖..
  11. sellTicket01.start();//启动售票线程
  12. sellTicket02.start();//启动售票线程
  13. sellTicket03.start();//启动售票线程
  14. }
  15. }
  16. //使用Thread方式
  17. class SellTicket01 extends Thread {
  18. private static int ticketNum = 100;//让多个线程共享 ticketNum
  19. @Override
  20. public void run() {
  21. while (true) {
  22. if (ticketNum <= 0) {
  23. System.out.println("售票结束...");
  24. break;
  25. }
  26. //休眠50毫秒, 模拟
  27. try {
  28. Thread.sleep(50);
  29. } catch (InterruptedException e) {
  30. e.printStackTrace();
  31. }
  32. System.out.println("窗口 " + Thread.currentThread().getName() + " 售出一张票"
  33. + " 剩余票数=" + (--ticketNum));
  34. }
  35. }
  36. }

image.png

使用实现 Runnable方式创建线程

  1. package test;
  2. /**
  3. * 使用多线程,模拟三个窗口同时售票100张
  4. */
  5. public class Main {
  6. public static void main(String[] args) {
  7. System.out.println("===使用实现接口方式来售票=====");
  8. SellTicket02 sellTicket02 = new SellTicket02();
  9. new Thread(sellTicket02).start();//第1个线程-窗口
  10. new Thread(sellTicket02).start();//第2个线程-窗口
  11. new Thread(sellTicket02).start();//第3个线程-窗口
  12. }
  13. }
  14. //实现接口方式
  15. class SellTicket02 implements Runnable {
  16. private int ticketNum = 100;//让多个线程共享 ticketNum
  17. @Override
  18. public void run() {
  19. while (true) {
  20. if (ticketNum <= 0) {
  21. System.out.println("售票结束...");
  22. break;
  23. }
  24. //休眠50毫秒, 模拟
  25. try {
  26. Thread.sleep(50);
  27. } catch (InterruptedException e) {
  28. e.printStackTrace();
  29. }
  30. System.out.println("窗口 " + Thread.currentThread().getName() + " 售出一张票"
  31. + " 剩余票数=" + (--ticketNum));//1 - 0 - -1 - -2
  32. }
  33. }
  34. }

image.png

解决方案:

线程同步机制