JAVA之旅(十五)——多线程的生产者和消费者,停止线程,守护线程,线程的优先级,setPriority设置优先级,yield临时停止…

释放双眼,带上耳机,听听看~!

JAVA之旅(十五)——多线程的生产者和消费者,停止线程,守护线程,线程的优先级,setPriority设置优先级,yield临时停止


我们接着多线程讲

一.生产者和消费者

什么是生产者和消费者?我们解释过来应该是生产一个,消费一个,的意思,具体我们通过例子来说


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
1package com.lgl.hellojava;
2
3//公共的   类   类名
4public class HelloJJAVA {
5
6    public static void main(String[] args) {
7        /**
8         * 生产者和消费者
9         */
10        Resrource res = new Resrource();
11
12        Produce pro = new Produce(res);
13        Consumer con = new Consumer(res);
14
15        Thread t1 = new Thread(pro);
16        Thread t2 = new Thread(con);
17
18        t1.start();
19        t2.start();
20
21    }
22}
23
24// 资源
25class Resrource {
26    private String name;
27    private int count = 1;
28    private boolean flag = false;
29
30    // 生产
31    public synchronized void set(String name) {
32
33        if (flag) {
34            try {
35                wait();
36            } catch (InterruptedException e) {
37                // TODO Auto-generated catch block
38                e.printStackTrace();
39            }
40
41            // 每次设置添加编号
42            this.name = name + "-" + count++;
43            System.out.println(Thread.currentThread().getName() + "--生产者--"
44                    + this.name);
45            flag = true;
46            this.notify();
47        }
48    }
49
50    // 消费
51    public synchronized void out() {
52
53        if (!flag)
54            try {
55                wait();
56            } catch (InterruptedException e) {
57                // TODO Auto-generated catch block
58                e.printStackTrace();
59            }
60        System.out.println(Thread.currentThread().getName() + "--消费者--"
61                + this.name);
62        flag = false;
63        this.notify();
64    }
65
66}
67
68// 生产
69class Produce implements Runnable {
70
71    private Resrource res;
72
73    public Produce(Resrource res) {
74        this.res = res;
75    }
76
77    @Override
78    public void run() {
79        while (true) {
80            System.out.println("Android");
81        }
82    }
83
84}
85
86// 消费
87class Consumer implements Runnable {
88    private Resrource res;
89
90    public Consumer(Resrource res) {
91        this.res = res;
92    }
93
94    @Override
95    public void run() {
96        while (true) {
97            res.out();
98        }
99    }
100
101}
102

当我们生产一个,消费一个,就具有多线程的特性,如果出现其他现象,那就说明你的线程存在安全隐患了

二.停止线程

怎么让线程停?你会想到stop方法

既然已过时,我们就的去想其他办法了,跟其原理,是什么?run方法结束就是线程停止,那怎么让run方法结束?

  • 只要控制循环,就可以让run方法结束,也就是线程的结束

我们写个实例


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
1package com.lgl.hellojava;
2
3import org.omg.CORBA.FloatHolder;
4
5//公共的   类   类名
6public class HelloJJAVA {
7
8    public static void main(String[] args) {
9        /**
10         * 线程停止
11         */
12        stopThread s = new stopThread();
13
14        Thread t1 = new Thread(s);
15        Thread t2 = new Thread(s);
16
17        t1.start();
18        t2.start();
19
20        int num = 0;
21
22        while (true) {
23
24            if (num++ == 60) {
25                s.changeFlag();
26                break;
27            } else {
28                System.out.println(Thread.currentThread().getName()
29                        + "Main run");
30            }
31        }
32    }
33}
34
35class stopThread implements Runnable {
36
37    private boolean flag = true;
38
39    @Override
40    public void run() {
41        while (flag) {
42            System.out.println(Thread.currentThread().getName() + "Thread run");
43        }
44    }
45
46    public void changeFlag() {
47        flag = false;
48    }
49
50}
51
52

逻辑十分简单,只要达到要求,就停止,但是还有一种特殊情况,当线程处于冻结状态,就不会读取到标记,那线程就不会结束,我们看


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
1package com.lgl.hellojava;
2
3import org.omg.CORBA.FloatHolder;
4
5//公共的   类   类名
6public class HelloJJAVA {
7
8    public static void main(String[] args) {
9        /**
10         * 线程停止
11         */
12        stopThread s = new stopThread();
13
14        Thread t1 = new Thread(s);
15        Thread t2 = new Thread(s);
16
17        t1.start();
18        t2.start();
19
20        int num = 0;
21
22        while (true) {
23
24            if (num++ == 60) {
25                s.changeFlag();
26                break;
27            } else {
28                System.out.println(Thread.currentThread().getName()
29                        + "Main run");
30            }
31        }
32    }
33}
34
35class stopThread implements Runnable {
36
37    private boolean flag = true;
38
39    @Override
40    public synchronized void run() {
41        while (flag) {
42
43            try {
44                wait();
45            } catch (InterruptedException e) {
46                System.out.println(Thread.currentThread().getName()
47                        + "InterruptedException run");
48            }
49            System.out.println(Thread.currentThread().getName() + "Thread run");
50        }
51    }
52
53    public void changeFlag() {
54        flag = false;
55    }
56
57}
58
59

这样就循环了。而在我们多线程中,提供了一个中断的方法Interupted

三.守护线程

守护线程其实也是Interupted中的东西,我们来看

你只要在启动线程前调用就可以了,就标记成了守护线程,就是一个依赖关系,你在我在,你不在我也不在;

四.Join方法

这个也是一个方法,意思是等待线程终止

我们倒是可以写个小例子


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
1package com.lgl.hellojava;
2
3//公共的   类   类名
4public class HelloJJAVA {
5
6    public static void main(String[] args) {
7        /**
8         * Join
9         */
10        Demo d = new Demo();
11        Thread t1 = new Thread(d);
12        Thread t2 = new Thread(d);
13
14        t1.start();
15
16        try {
17            // t1要申请加入到运行中来
18            t1.join();
19        } catch (InterruptedException e) {
20            // TODO Auto-generated catch block
21            e.printStackTrace();
22        }
23        t2.start();
24
25        for (int i = 0; i < 100; i++) {
26            System.out.println("miam" + i);
27        }
28        System.out.println("main over");
29    }
30}
31
32class Demo implements Runnable {
33
34    @Override
35    public void run() {
36        for (int i = 0; i < 100; i++) {
37            System.out.println(Thread.currentThread().getName() + "=---" + i);
38        }
39    }
40
41}
42
43

我们可以满足条件下 ,临时加入一个线程

当A线程执行到了B线程的join方法时,A线程就会等待,等B线程都执行完,A才会执行,A可以用来临时加入线程执行。

五.线程的优先级

线程有优先级,默认的优先级都是5,这个是可以改变的,t1.setPriority(优先级);

我们可以拿上面的例子来做个比较


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
1package com.lgl.hellojava;
2
3//公共的   类   类名
4public class HelloJJAVA {
5
6    public static void main(String[] args) {
7        /**
8         * Join
9         */
10        Demo d = new Demo();
11        Thread t1 = new Thread(d);
12        Thread t2 = new Thread(d);
13
14        t1.start();
15        //权限虽然高,只是频率高而已
16        t1.setPriority(Thread.MAX_PRIORITY);
17        t2.start();
18
19        for (int i = 0; i < 100; i++) {
20            System.out.println("miam" + i);
21        }
22        System.out.println("main over");
23    }
24}
25
26class Demo implements Runnable {
27
28    @Override
29    public void run() {
30        for (int i = 0; i < 100; i++) {
31            System.out.println(Thread.currentThread().getName() + "=---" + i);
32        }
33    }
34
35}
36
37

我们这里还有一个小方法yield,临时停止的意思,我们可以看例子


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
1package com.lgl.hellojava;
2
3//公共的   类   类名
4public class HelloJJAVA {
5
6    public static void main(String[] args) {
7        /**
8         * Join
9         */
10        Demo d = new Demo();
11        Thread t1 = new Thread(d);
12        Thread t2 = new Thread(d);
13
14        t1.start();
15        t2.start();
16
17        for (int i = 0; i < 100; i++) {
18            // System.out.println("miam" + i);
19        }
20        System.out.println("main over");
21    }
22}
23
24class Demo implements Runnable {
25
26    @Override
27    public void run() {
28        for (int i = 0; i < 100; i++) {
29            System.out.println(Thread.currentThread().getName() + "=---" + i);
30            Thread.yield();
31        }
32    }
33
34}
35
36

我们可以看到

主线程并没有运行,那就对了,因为暂停了

我们到这里,本篇就结束了,同时线程所讲的知识也讲完了,线程博大精深,很值得我们学习,我所讲的,仍然只是一些皮毛罢了,希望大家多用心研究一下

我的群555974449也可以欢迎各位来讨论

给TA打赏
共{{data.count}}人
人已打赏
安全技术

Bootstrap 间隔 (Spacing)

2021-12-21 16:36:11

安全技术

从零搭建自己的SpringBoot后台框架(二十三)

2022-1-12 12:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索