案例1:

(1)在main方法中启动两个线程
(2)第1个线程循环随机打印100以内的整数
(3)直到第2个线程从键盘读取了“Q”命令。

  1. package test;
  2. import java.util.Scanner;
  3. public class Main {
  4. public static void main(String[] args) {
  5. A a = new A();
  6. B b = new B(a);//一定要注意.
  7. a.start();
  8. b.start();
  9. }
  10. }
  11. //创建A线程类
  12. class A extends Thread {
  13. private boolean loop = true;
  14. @Override
  15. public void run() {
  16. //输出1-100数字
  17. while (loop) {
  18. System.out.println((int)(Math.random() * 100 + 1));
  19. //休眠
  20. try {
  21. Thread.sleep(1000);
  22. } catch (InterruptedException e) {
  23. e.printStackTrace();
  24. }
  25. }
  26. System.out.println("a线程退出...");
  27. }
  28. public void setLoop(boolean loop) {//可以修改loop变量
  29. this.loop = loop;
  30. }
  31. }
  32. //直到第2个线程从键盘读取了“Q”命令
  33. class B extends Thread {
  34. private A a;
  35. private Scanner scanner = new Scanner(System.in);
  36. public B(A a) {//构造器中,直接传入A类对象
  37. this.a = a;
  38. }
  39. @Override
  40. public void run() {
  41. while (true) {
  42. //接收到用户的输入
  43. System.out.println("请输入你指令(Q)表示退出:");
  44. char key = scanner.next().toUpperCase().charAt(0);
  45. if(key == 'Q') {
  46. //以通知的方式结束a线程
  47. a.setLoop(false);
  48. System.out.println("b线程退出.");
  49. break;
  50. }
  51. }
  52. }
  53. }

image.png

案例2:

(1)有2个用户分别从同一个卡上取钱(总额:10000)
(2)每次都取1000,当余额不足时,就不能取款了
(3)不能出现超取现象=》线程同步问题.

  1. package test;
  2. public class Main {
  3. public static void main(String[] args) {
  4. T t = new T();
  5. Thread thread1 = new Thread(t);
  6. thread1.setName("t1");
  7. Thread thread2 = new Thread(t);
  8. thread2.setName("t2");
  9. thread1.start();
  10. thread2.start();
  11. }
  12. }
  13. //编程取款的线程
  14. //1.因为这里涉及到多个线程共享资源,所以我们使用实现Runnable方式
  15. //2. 每次取出 1000
  16. class T implements Runnable {
  17. private int money = 10000;
  18. @Override
  19. public void run() {
  20. while (true) {
  21. //解读
  22. //1. 这里使用 synchronized 实现了线程同步
  23. //2. 当多个线程执行到这里时,就会去争夺 this对象锁
  24. //3. 哪个线程争夺到(获取)this对象锁,就执行 synchronized 代码块, 执行完后,会释放this对象锁
  25. //4. 争夺不到this对象锁,就blocked ,准备继续争夺
  26. //5. this对象锁是非公平锁.
  27. synchronized (this) {//
  28. //判断余额是否够
  29. if (money < 1000) {
  30. System.out.println("余额不足");
  31. break;
  32. }
  33. money -= 1000;
  34. System.out.println(Thread.currentThread().getName() + " 取出了1000 当前余额=" + money);
  35. }
  36. //休眠1s
  37. try {
  38. Thread.sleep(1000);
  39. } catch (InterruptedException e) {
  40. e.printStackTrace();
  41. }
  42. }
  43. }
  44. }

image.png