Java多线程

1.线程简介

  进程:是执行程序的一次执行过程。

  线程:是CPU调度和执行的单位,通常在一个进程中会包含若干个线程。

    main()称之为主线程,为程序的入口,用于执行整个程序。

2.线程创建

  方法1:

 1 package X.Study.demo01;
 2 
 3 //创建线程方式一:继承Thread类,重写run()方法,调用start开启线程
 4 public class TestThread1 extends Thread {
 5     @Override
 6     public void run() {
 7         //run方法线程体
 8         for (int i = 0; i < 20; i++) {
 9             System.out.println("我在看代码---" + i);
10         }
11     }
12 
13     //main线程,主线程
14     public static void main(String[] args) {
15 
16         //创建一个线程对象
17         TestThread1 testThread1 = new TestThread1();
18         //调用start()方法开启线程
19         testThread1.start();
20 
21 
22         for (int i = 0; i < 20; i++) {
23             System.out.println("我在学线程---" + i);
24         }
25     }
26 }

  方法二:

 1 package X.Study.demo01;
 2 
 3 //实现runnable接口,重写run方法,执行线程需要丢入runnable接口实现类,调用start()方法
 4 public class TestThread2 implements Runnable {
 5     @Override
 6     public void run() {
 7         for (int i = 0; i < 20; i++) {
 8             System.out.println("我在看代码" + i);
 9         }
10     }
11 
12     public static void main(String[] args) {
13         //创建runnable接口的实现类对象
14         TestThread2 testThread2 = new TestThread2();
15         //创建线程对象,铜锅线程对象开启线程
16         Thread thread = new Thread(testThread2);
17         thread.start();
18 
19 
20         for (int i = 0; i < 20; i++) {
21             System.out.println("我在学习" + i);
22         }
23     }
24 }

模拟龟兔赛跑

 1 package X.Study.demo01;
 2 
 3 
 4 public class Race implements Runnable {
 5 
 6     private static String winner;
 7 
 8     @Override
 9     public void run() {
10         for (int i = 0; i <= 100; i++) {
11             //模拟兔子睡觉
12             if (Thread.currentThread().getName().equals("兔子")&&i%10==0){
13                 try {
14                     Thread.sleep(200);
15                 } catch (InterruptedException e) {
16                     e.printStackTrace();
17                 }
18             }
19 
20             boolean flag = gameOver(i);
21             if (flag) {
22                 break;
23             }
24             System.out.println(Thread.currentThread().getName() + "跑了" + i + "步");
25         }
26 
27     }
28 
29     public boolean gameOver(int step) {
30         if (winner != null) {
31             return true;
32         }
33         {
34             if (step >= 100) {
35                 winner = Thread.currentThread().getName();
36                 System.out.println("winner is" + winner);
37                 return true;
38             }
39         }
40         return false;
41     }
42 
43     public static void main(String[] args) {
44         Race race = new Race();
45         new Thread(race, "兔子").start();
46         new Thread(race, "乌龟").start();
47 
48     }
49 }

 3.静态代理

  

 1 package X.Study.demo02;
 2 
 3 public class StaticProxy {
 4     public static void main(String[] args) {
 5         You you = new You();
 6         WeddingCompany weddingCompany = new WeddingCompany(you);
 7         weddingCompany.happyMarry();
 8 
 9     }
10 }
11 
12 interface Marry {
13     void happyMarry();
14 }
15 
16 //真实角色,你去结婚
17 class You implements Marry {
18     @Override
19     public void happyMarry() {
20         System.out.println("我要结婚了");
21     }
22 }
23 
24 //代理公司,帮你准备结婚
25 class WeddingCompany implements Marry {
26 
27     private Marry target;
28 
29     public WeddingCompany(Marry target) {
30         this.target = target;
31     }
32 
33     @Override
34     public void happyMarry() {
35         before();
36         this.target.happyMarry();
37         after();
38     }
39 
40     private void before() {
41         System.out.println("结婚前准备");
42     }
43 
44     private void after() {
45         System.out.println("结婚后收礼金");
46     }
47 }

  总结:

    1.真实对象和代理对象都要实现同一个接口

    2.代理对象要代理真实角色

 

4.Lambda表达式

 1 package X.Study.demo03;
 2 
 3 public class TestLamda {
 4 
 5     //3.静态内部类
 6     static class Like2 implements ILike {
 7         @Override
 8         public void lamda() {
 9             System.out.println("I like lamda2");
10         }
11     }
12 
13     public static void main(String[] args) {
14 
15         ILike like = new Like();
16         like.lamda();
17 
18         like = new Like2();
19         like.lamda();
20 
21 
22         //4.局部内部类,放到main()方法里
23         class Like3 implements ILike {
24             @Override
25             public void lamda() {
26                 System.out.println("I like lamda3");
27             }
28         }
29         like = new Like3();
30         like.lamda();
31 
32 
33         //5.匿名内部类,没有类的名称,必须借助接口或者父类
34         like = new ILike() {
35             @Override
36             public void lamda() {
37                 System.out.println("I like lamda4");
38             }
39         };
40         like.lamda();
41 
42 
43         //6.用lamda简化
44         like=()->{
45             System.out.println("I like lamda5");
46         };
47         like.lamda();
48 
49 
50     }
51 
52 
53 }
54 
55 //定义一个函数式接口:只包含一个抽象方法
56 interface ILike {
57     void lamda();
58 }
59 
60 //实现类
61 class Like implements ILike {
62     @Override
63     public void lamda() {
64         System.out.println("I like lamda");
65     }
66 }

 

 1 package X.Study.demo03;
 2 
 3 public class TestLambda02 {
 4     public static void main(String[] args) {
 5         /*ILove love=new Love();
 6         love.love(20);*/
 7 
 8         ILove love = null;
 9         /*//Lambda简化
10         love = (int a) -> {
11             System.out.println("I love you" + a);
12         };
13         love.love(520);*/
14 
15         /*//简化1:去掉参数类型
16         love = (a) -> {
17             System.out.println("I love you" + a);
18         };
19         love.love(521);*/
20 
21        /* //简化2:简化括号
22         love = a -> {
23             System.out.println("I love you" + a);
24         };
25         love.love(521520);*/
26 
27         //简化3:去掉花括号
28         love = a ->
29                 System.out.println("I love you" + a);
30         
31         love.love(521520521);
32     }
33 
34 
35     interface ILove {
36         void love(int a);
37     }
38 
39     class Love implements ILove {
40         @Override
41         public void love(int a) {
42             System.out.println("I love you" + a);
43         }
44     }
45 }

  总结:

    1.Lambda表达式只有一行代码的情况下才能简化成一行,如果有多行,需要用代码块包裹

    2.前提接口为函数式接口

    3.多个参数也可以去掉参数类型,要去掉就都去掉,必须加上括号

 

5.线程状态

  5.1 线程停止

  

 1 package X.Study.demo04;
 2 
 3 //测试stop
 4 //1.建议线程正常停止-->利用次数,不建议死循环
 5 //2.建议使用标志位-->设置一个标志位
 6 //3.不要使用stop或者destory等JDK不建议使用的方法
 7 public class TestStop implements Runnable {
 8 
 9     //设置一个标识位
10     private boolean flag = true;
11 
12     @Override
13     public void run() {
14         int i = 0;
15         while (flag) {
16             System.out.println("run......Thread" + i++);
17         }
18     }
19 
20     //设置一个公开的方法停止线程,转换标志位
21     public void stop() {
22         this.flag = false;
23     }
24 
25     public static void main(String[] args) {
26 
27         TestStop testStop = new TestStop();
28         new Thread(testStop).start();
29 
30         for (int i = 0; i < 1000; i++) {
31             System.out.println("main" + i);
32             if (i == 900) {
33                 //调用stop方法切换标志位,停止线程
34                 testStop.stop();
35                 System.out.println("线程停止了");
36             }
37 
38         }
39     }
40 }

 

  5.2 线程休眠

    

 1 package X.Study.demo04;
 2 
 3 //模拟网络延时:放大问题的发生性
 4 public class TestSleep implements Runnable {
 5 
 6     private int ticketNum = 10;
 7 
 8     @Override
 9     public void run() {
10         while (true) {
11             if (ticketNum <= 0) {
12                 break;
13             }
14             try {//快捷键ctrl+alt+t
15                 Thread.sleep(100);
16             } catch (InterruptedException e) {
17                 e.printStackTrace();
18             }
19             System.out.println(Thread.currentThread().getName() + "拿到了第---->" + ticketNum-- + "张票");
20         }
21     }
22 
23     public static void main(String[] args) {
24         TestSleep ticket = new TestSleep();
25         new Thread(ticket, "小明").start();
26         new Thread(ticket, "小红").start();
27         new Thread(ticket, "小黑").start();
28     }
29 }
 1 package X.Study.demo04;
 2 
 3 import javax.xml.crypto.Data;
 4 import java.text.SimpleDateFormat;
 5 import java.util.Date;
 6 
 7 public class TestSleep02 {
 8 
 9     public static void main(String[] args) {
10         /*try {
11             tenDown();
12         } catch (InterruptedException e) {
13             e.printStackTrace();
14         }*/
15 
16         //打印当前系统时间
17         Date startTime=new Date(System.currentTimeMillis());//获取当前系统时间
18         while(true){
19             try {
20                 Thread.sleep(1000);
21                 System.out.println(new SimpleDateFormat("HH:mm:ss").format(startTime));
22                 startTime=new Date(System.currentTimeMillis());//更新当前时间
23             } catch (InterruptedException e) {
24                 e.printStackTrace();
25             }
26 
27 
28         }
29     }
30     //模拟倒计时
31     public static void tenDown() throws InterruptedException {
32         int num=10;
33 
34         while (true){
35             Thread.sleep(1000);
36             System.out.println(num--);
37             if(num<=0){
38                 break;
39             }
40         }
41     }
42 }

  

  5.3 线程礼让

 1 package X.Study.demo04;
 2 
 3 //礼让不一定成功,看CPU心情
 4 public class TestYeild {
 5     public static void main(String[] args) {
 6         MyThread myThread = new MyThread();
 7         new Thread(myThread,"前戏").start();
 8         new Thread(myThread,"PAPA").start();
 9     }
10 }
11 
12 class MyThread implements Runnable{
13     @Override
14     public void run() {
15         System.out.println(Thread.currentThread().getName()+"线程开始执行");
16         Thread.yield();//礼让线程
17         System.out.println(Thread.currentThread().getName()+"线程停止执行");
18     }
19 }

 

  5.4 线程强制执行

 1 package X.Study.demo04;
 2 
 3 public class TestJoin implements Runnable {
 4     @Override
 5     public void run() {
 6         for (int i = 0; i < 1000; i++) {
 7             System.out.println("线程VIP来了-->" + i);
 8         }
 9     }
10 
11     public static void main(String[] args) throws InterruptedException {
12 
13         //启动线程,利用代理
14         TestJoin testJoin = new TestJoin();
15         Thread thread = new Thread(testJoin);
16         thread.start();
17 
18         for (int i = 0; i < 500; i++) {
19             if (i == 200) {
20                 thread.join();//插队
21             }
22             System.out.println("main" + i);
23         }
24     }
25 }

  5.6 观测线程状态

 1 package X.Study.demo04;
 2 
 3 //观测线程状态
 4 public class TestState {
 5     public static void main(String[] args) throws InterruptedException {
 6         Thread thread = new Thread(() -> {
 7             try {
 8                 Thread.sleep(1000);
 9             } catch (Exception e) {
10                 e.printStackTrace();
11             }
12             System.out.println("/////");
13         });
14 
15         //观察状态
16         Thread.State state = thread.getState();
17         System.out.println(state);
18 
19         //观察启动后
20         thread.start();//启动线程
21         state = thread.getState();
22         System.out.println(state);
23 
24         while (state != Thread.State.TERMINATED) {
25             Thread.sleep(100);
26             state = thread.getState();
27             System.out.println(state);
28         }
29     }
30 
31 }
 1 package X.Study.demo04;
 2 
 3 //观测线程状态
 4 public class TestState {
 5     public static void main(String[] args) throws InterruptedException {
 6         Thread thread = new Thread(() -> {
 7             try {
 8                 Thread.sleep(1000);
 9             } catch (Exception e) {
10                 e.printStackTrace();
11             }
12             System.out.println("/////");
13         });
14 
15         //观察状态
16         Thread.State state = thread.getState();
17         System.out.println(state);
18 
19         //观察启动后
20         thread.start();//启动线程
21         state = thread.getState();
22         System.out.println(state);
23 
24         while (state != Thread.State.TERMINATED) {
25             Thread.sleep(100);
26             state = thread.getState();
27             System.out.println(state);
28         }
29     }
30 
31 }

   5.7 线程优先级

  

 1 package X.Study.demo04;
 2 
 3 public class TestPriority {
 4 
 5     public static void main(String[] args) {
 6         //主线程默认优先级5
 7         System.out.println(Thread.currentThread().getName() + "-->" + Thread.currentThread().getPriority());
 8 
 9         myPrioritor myPrioritor = new myPrioritor();
10         Thread t1 = new Thread(myPrioritor);
11         Thread t2 = new Thread(myPrioritor);
12         Thread t3 = new Thread(myPrioritor);
13         Thread t4 = new Thread(myPrioritor);
14         Thread t5 = new Thread(myPrioritor);
15         Thread t6 = new Thread(myPrioritor);
16         //先设置优先级在启动
17         t1.start();
18 
19         t2.setPriority(1);
20         t2.start();
21 
22         t3.setPriority(10);
23         t3.start();
24 
25         t4.setPriority(8);
26         t4.start();
27 
28         t5.setPriority(2);
29         t5.start();
30 
31         t6.setPriority(3);
32         t6.start();
33     }
34 
35 
36 }
37 
38 class myPrioritor implements Runnable {
39     @Override
40     public void run() {
41         System.out.println(Thread.currentThread().getName() + "-->" + Thread.currentThread().getPriority());
42     }
43 }

  

  5.8 守护线程

 1 package X.Study.demo04;
 2 
 3 //测试守护线程
 4 //上帝保佑你
 5 public class TestDaemon {
 6     public static void main(String[] args) {
 7         God god = new God();
 8         You you = new You();
 9 
10         Thread thread = new Thread(god);
11         thread.setDaemon(true);//默认是false,表示用户线程,正常的线程都是用户线程
12         thread.start();//上帝守护线程启动
13 
14         new Thread(you).start();//你 用户线程启动
15 
16 
17     }
18 }
19 
20 //上帝
21 class God implements Runnable {
22     @Override
23     public void run() {
24         while (true) {
25             System.out.println("上帝保佑着你");
26         }
27     }
28 }
29 
30 //
31 class You implements Runnable {
32     @Override
33     public void run() {
34         for (int i = 0; i < 36500; i++) {
35             System.out.println("我每天开心地活着");
36         }
37         System.out.println("sayGoodbye this World!");
38     }
39 }

 

6 线程同步

  队列+锁

  6.1 线程不安全案例

 

 1 package X.Study.syn;
 2 
 3 //测试不安全的买票
 4 //线程不安全,有负数
 5 public class UnsafeBuyTickets {
 6     public static void main(String[] args) {
 7         ByTickets byTickets = new ByTickets();
 8 
 9         new Thread(byTickets, "小明").start();
10         new Thread(byTickets, "小绿").start();
11         new Thread(byTickets, "小黑").start();
12     }
13 }
14 
15 
16 class ByTickets implements Runnable {
17 
18     private int ticketNums = 10;
19     boolean flag = true;//设置一个标志位,用于线程停止
20 
21     @Override
22     public void run() {
23         //买票
24         while (flag) {
25             try {
26                 buy();
27             } catch (Exception e) {
28                 e.printStackTrace();
29             }
30         }
31 
32     }
33 
34     //判断是否有票
35     private void buy() {
36         if (ticketNums <= 0) {
37             flag = false;//线程停止
38             return;
39         }
40 
41         try {
42             Thread.sleep(100);
43         } catch (InterruptedException e) {
44             e.printStackTrace();
45         }
46         //买票
47         System.out.println(Thread.currentThread().getName() + "拿到了第" + ticketNums-- + "张票");
48     }
49 }
 1 package X.Study.syn;
 2 
 3 //模拟银行取款
 4 //线程不安全,有负数
 5 public class UnsafeBank {
 6     public static void main(String[] args) {
 7         Account account = new Account(100, "基金");
 8 
 9         Drawing You = new Drawing(account, 50, "你");
10         Drawing GirlFriend = new Drawing(account, 100, "女人");
11 
12         You.start();
13         GirlFriend.start();
14     }
15 }
16 
17 
18 //账户
19 class Account {
20     int money;//余额
21     String name;//名字
22 
23     public Account(int money, String name) {
24         this.money = money;
25         this.name = name;
26     }
27 }
28 
29 //银行,模拟取款
30 class Drawing extends Thread {
31     Account account;//账户
32     int drawingMoney;//取了多少钱
33     int nowMoney;//现在有多少钱
34 
35     public Drawing(Account account, int drawingMoney, String name) {
36         super(name);
37         this.drawingMoney = drawingMoney;
38         this.account = account;
39     }
40 
41     //取钱
42     @Override
43     public void run() {
44         //判断是否有钱
45         if (account.money - drawingMoney < 0) {
46             System.out.println(Thread.currentThread().getName() + "钱不够了");
47             return;
48         }
49 
50         //sleep可以放大问题的发生性
51         try {
52             Thread.sleep(1000);
53         } catch (InterruptedException e) {
54             e.printStackTrace();
55         }
56         //卡内余额
57         account.money = account.money - drawingMoney;
58         //你手里的钱
59         nowMoney = nowMoney + drawingMoney;
60 
61         System.out.println(account.name + "余额为" + account.money);
62 
63         System.out.println(this.getName() + "手里的钱:" + nowMoney);
64 
65     }
66 }

   6.2 同步方法及同步块

  

 1 package X.Study.syn;
 2 
 3 //测试买票
 4 public class UnsafeBuyTickets {
 5     public static void main(String[] args) {
 6         ByTickets byTickets = new ByTickets();
 7 
 8         new Thread(byTickets, "小明").start();
 9         new Thread(byTickets, "小绿").start();
10         new Thread(byTickets, "小黑").start();
11     }
12 }
13 
14 
15 class ByTickets implements Runnable {
16 
17     private int ticketNums = 10;
18     boolean flag = true;//设置一个标志位,用于线程停止
19 
20     @Override
21     public void run() {
22         //买票
23         while (flag) {
24             try {
25                 buy();
26             } catch (Exception e) {
27                 e.printStackTrace();
28             }
29         }
30 
31     }
32 
33     //判断是否有票
34     private synchronized void buy() {//synchronized默认锁的是this.
35         if (ticketNums <= 0) {
36             flag = false;//线程停止
37             return;
38         }
39 
40         try {
41             Thread.sleep(100);
42         } catch (InterruptedException e) {
43             e.printStackTrace();
44         }
45         //买票
46         System.out.println(Thread.currentThread().getName() + "拿到了第" + ticketNums-- + "张票");
47     }
48 }
 1 package X.Study.syn;
 2 
 3 //模拟银行取款
 4 public class UnsafeBank {
 5     public static void main(String[] args) {
 6         Account account = new Account(100, "基金");
 7 
 8         Drawing You = new Drawing(account, 50, "你");
 9         Drawing GirlFriend = new Drawing(account, 100, "女人");
10 
11         You.start();
12         GirlFriend.start();
13     }
14 }
15 
16 
17 //账户
18 class Account {
19     int money;//余额
20     String name;//名字
21 
22     public Account(int money, String name) {
23         this.money = money;
24         this.name = name;
25     }
26 }
27 
28 //银行,模拟取款
29 class Drawing extends Thread {
30     Account account;//账户
31     int drawingMoney;//取了多少钱
32     int nowMoney;//现在有多少钱
33 
34     public Drawing(Account account, int drawingMoney, String name) {
35         super(name);
36         this.drawingMoney = drawingMoney;
37         this.account = account;
38     }
39 
40     //取钱
41     @Override
42     public void run() {
43         //判断是否有钱
44         //同步块
45         //锁的对象就是变化的量,需要增删改的对象
46         synchronized (account){
47             if (account.money - drawingMoney < 0) {
48                 System.out.println(Thread.currentThread().getName() + "钱不够了");
49                 return;
50         }
51             try {
52                 Thread.sleep(1000); //sleep可以放大问题的发生性
53             } catch (InterruptedException e) {
54                 e.printStackTrace();
55             }
56             //卡内余额
57             account.money = account.money - drawingMoney; 
58             //你手里的钱
59             nowMoney = nowMoney + drawingMoney;
60 
61             System.out.println(account.name + "余额为" + account.money);
62 
63             System.out.println(this.getName() + "手里的钱:" + nowMoney);
64     }
65 
66 
67 
68 
69     }
70 }

 6.3 死锁

    多个线程互相抱着对方需要的资源,然后形成僵持。

 1 package X.Study.deadLock;
 2 
 3 public class DeadLock {
 4     public static void main(String[] args) {
 5         MakeUP g1 = new MakeUP(0, "小绿");
 6         MakeUP g2 = new MakeUP(1, "小蓝");
 7 
 8         g1.start();
 9         g2.start();
10 
11 
12     }
13 }
14 
15 //口红
16 class Lipstick {
17 }
18 
19 //镜子
20 class Mirror {
21 }
22 
23 
24 class MakeUP extends Thread {
25     //需要的资源,用static保证只有一份
26     static Lipstick lipstick = new Lipstick();
27     static Mirror mirror = new Mirror();
28 
29     int choice;//选择
30     String girlName;//使用化妆品的人
31 
32     MakeUP(int choice, String girlName) {
33         this.choice = choice;
34         this.girlName = girlName;
35     }
36 
37     @Override
38     public void run() {
39         try {
40             makeup();//化妆
41         } catch (Exception e) {
42             e.printStackTrace();
43         }
44 
45     }
46 
47     //化妆
48     private void makeup() {
49         if (choice == 0) {
50             synchronized (lipstick) {//获得口红的锁
51                 System.out.println(this.girlName + "获得口红的锁");
52                 try {
53                     Thread.sleep(1000);
54                 } catch (InterruptedException e) {
55                     e.printStackTrace();
56                 }
57 
58                 synchronized (mirror) {//一秒钟后,想获得镜子
59                     System.out.println(this.girlName + "获得镜子的锁");
60                 }
61             }
62         } else {
63             synchronized (mirror) {//获得镜子的锁
64                 System.out.println(this.girlName + "获得镜子的锁");
65                 try {
66                     Thread.sleep(2000);
67                 } catch (InterruptedException e) {
68                     e.printStackTrace();
69                 }
70 
71                 synchronized (lipstick) {//两秒钟后,想获得口红
72                     System.out.println(this.girlName + "获得口红的锁");
73                 }
74 
75             }
76 
77 
78         }
79     }
80 }

两个人都需要获得对方的资源,程序执行会导致死锁
解决办法:把资源拿出对方的锁
 1 private void makeup() {
 2         if (choice == 0) {
 3             synchronized (lipstick) {//获得口红的锁
 4                 System.out.println(this.girlName + "获得口红的锁");
 5                 try {
 6                     Thread.sleep(1000);
 7                 } catch (InterruptedException e) {
 8                     e.printStackTrace();
 9                 }
10             }
11             synchronized (mirror) {//一秒钟后,想获得镜子
12                 System.out.println(this.girlName + "获得镜子的锁");
13             }
14         } else {
15             synchronized (mirror) {//获得镜子的锁
16                 System.out.println(this.girlName + "获得镜子的锁");
17                 try {
18                     Thread.sleep(2000);
19                 } catch (InterruptedException e) {
20                     e.printStackTrace();
21                 }
22             }
23 
24             synchronized (lipstick) {//两秒钟后,想获得口红
25                 System.out.println(this.girlName + "获得口红的锁");
26             }
27         }
28     }

 

6.4 lock锁

 1 package X.Study.Gaoji;
 2 
 3 import java.util.concurrent.locks.ReentrantLock;
 4 
 5 public class TestLock {
 6     public static void main(String[] args) {
 7         TestLock1 testLock = new TestLock1();
 8 
 9 
10         new Thread(testLock).start();
11         new Thread(testLock).start();
12         new Thread(testLock).start();
13     }
14 }
15 
16 class TestLock1 implements Runnable {
17 
18     int ticketNums = 10;
19     //定义lock锁
20     private final ReentrantLock lock = new ReentrantLock();
21 
22     @Override
23     public void run() {
24         while (true) {
25             try {
26                 lock.lock();//加锁
27                 if (ticketNums > 0) {
28                     try {
29                         Thread.sleep(1000);
30                     } catch (InterruptedException e) {
31                         e.printStackTrace();
32                     }
33                     System.out.println(ticketNums--);
34                 } else {
35                     break;
36                 }
37             } finally {
38                 lock.unlock();
39             }
40 
41         }
42     }
43 }

 

7.线程协作

   7.1 生产者/消费者模型:管程法

  

  1 package X.Study.Gaoji;
  2 //测试:生产者/消费者模型-->利用缓冲区解决:管程法
  3 
  4 //需要生产者,消费者,产品,缓冲区
  5 public class TestPC {
  6     public static void main(String[] args) {
  7         SynContainer container = new SynContainer();
  8 
  9         new Productor(container).start();
 10         new Consumer(container).start();
 11 
 12     }
 13 }
 14 
 15 
 16 //生产者
 17 class Productor extends Thread {
 18     SynContainer container;
 19 
 20     public Productor(SynContainer container) {
 21         this.container = container;
 22     }
 23     //生产
 24 
 25     @Override
 26     public void run() {
 27         for (int i = 0; i < 100; i++) {
 28             System.out.println("生产了" + i + "只鸡");
 29             container.push(new Chicken(i));
 30         }
 31     }
 32 }
 33 
 34 //消费者
 35 class Consumer extends Thread {
 36     SynContainer container;
 37 
 38     public Consumer(SynContainer container) {
 39         this.container = container;
 40     }
 41 
 42     //消费
 43 
 44     @Override
 45     public void run() {
 46         for (int i = 0; i < 100; i++) {
 47             System.out.println("消费了-->" + container.pop().id + "只鸡");
 48         }
 49     }
 50 }
 51 
 52 //产品
 53 class Chicken {
 54     int id;
 55 
 56     public Chicken(int id) {
 57         this.id = id;
 58     }
 59 
 60 }
 61 
 62 //缓冲区
 63 class SynContainer {
 64     //需要一个容器
 65     Chicken[] chickens = new Chicken[10];
 66 
 67     //容器计数器
 68     int count = 0;
 69 
 70     //生产者放入产品
 71     public synchronized void push(Chicken chicken) {
 72         //如果容器满了,需要等待消费者消费
 73         if (count == chickens.length) {
 74             //通知消费者消费,生产等待
 75             try {
 76                 this.wait();
 77             } catch (InterruptedException e) {
 78                 e.printStackTrace();
 79             }
 80         }
 81         //如果没有满,我们需要丢入产品
 82         chickens[count] = chicken;
 83         count++;
 84         this.notifyAll();
 85     }
 86 
 87     //消费者消费产品
 88     public synchronized Chicken pop() {
 89         //判断能否消费
 90         if (count == 0) {
 91             //等待生产者生产
 92             try {
 93                 this.wait();
 94             } catch (InterruptedException e) {
 95                 e.printStackTrace();
 96             }
 97         }
 98 
 99         //如果可以消费
100         count--;
101         Chicken chicken = chickens[count];
102 
103         //拿走后,通知生产者生产
104         this.notifyAll();//解除等待
105 
106 
107         return chicken;
108     }
109 }

  7.2 生产者/消费者模型:信号灯法

 1 package X.Study.Gaoji;
 2 
 3 //信号灯法:标志位解决
 4 public class TestPC2 {
 5     public static void main(String[] args) {
 6         TV tv = new TV();
 7 
 8         new Player(tv).start();
 9         new Watcher(tv).start();
10     }
11 }
12 
13 
14 //生产者:演员
15 class Player extends Thread {
16     TV tv;
17 
18     public Player(TV tv) {
19         this.tv = tv;
20     }
21 
22     @Override
23     public void run() {
24         for (int i = 0; i < 20; i++) {
25             if (i % 2 == 0) {
26                 this.tv.play("明星大侦探播放中");
27             } else {
28                 this.tv.play("不好意思,推送广告中");
29             }
30         }
31     }
32 }
33 
34 //消费者:观众
35 class Watcher extends Thread {
36     TV tv;
37 
38     public Watcher(TV tv) {
39         this.tv = tv;
40     }
41 
42     @Override
43     public void run() {
44         for (int i = 0; i < 20; i++) {
45             tv.watch();
46         }
47     }
48 
49 
50 }
51 
52 //产品:节目
53 class TV {
54     //演员表演,观众等待
55     //观众观看,演员等待
56     String voice;//表演的节目
57     boolean flag = true;//标志位
58 
59     //表演
60     public synchronized void play(String voice) {
61         if (!flag) {
62             try {
63                 this.wait();
64             } catch (InterruptedException e) {
65                 e.printStackTrace();
66             }
67         }
68         System.out.println("演员表演了" + voice);
69         //通知观众观看
70         this.notifyAll();
71         this.voice = voice;
72         this.flag = !this.flag;
73     }
74 
75     //观看
76     public synchronized void watch() {
77         if (flag) {
78             try {
79                 this.wait();
80             } catch (InterruptedException e) {
81                 e.printStackTrace();
82             }
83         }
84         System.out.println("观看了" + voice);
85         //通知演员表演
86         this.notifyAll();
87         this.flag = !this.flag;
88     }
89 }

  7.3 线程池

 1 package X.Study.Gaoji;
 2 
 3 import java.util.concurrent.Executor;
 4 import java.util.concurrent.ExecutorService;
 5 import java.util.concurrent.Executors;
 6 
 7 public class TestPool {
 8     public static void main(String[] args) {
 9         //1.创建服务,创建线程池
10         ExecutorService service = Executors.newFixedThreadPool(10);
11 
12         //2.执行
13         service.execute(new MyThread());
14         service.execute(new MyThread());
15         service.execute(new MyThread());
16         service.execute(new MyThread());
17 
18         //3.关闭链接
19         service.shutdown();
20 
21 
22     }
23 }
24 
25 class MyThread implements Runnable {
26     @Override
27     public void run() {
28         System.out.println(Thread.currentThread().getName());
29     }
30 }

 

posted @ 2022-04-04 21:36  King_X  阅读(48)  评论(0)    收藏  举报