线程状态&线程控制

线程状态

 

新建状态

new Thread() 后 该线程处于新建状态,与其他Java对象一样,未表现出线程的特征;

 

就绪状态

当 Thread的对象 调用了 start方法后,该线程处于 就绪状态;

JVM会为当前线程创建 运行时环境(虚拟机栈、程序计数器);

处于 就绪状态的线程 并未开始执行,需要等待CPU的调度;

 

运行状态

处于就绪状态的线程 获得CPU后,开始执行run方法,此时该线程处于 运行状态;

 

阻塞状态

如下情况,处于运行状态的线程将进入阻塞状态:

  线程 主动调用 sleep方法,放弃CPU资源;

  线程 调用了阻塞IO的方法,在方法返回之前,将被阻塞;

  线程 试图获取同步监视器,但 该同步监视器被其他线程持有

  线程 等待某个通知(notify);  

  线程 主动调用suspend,将线程挂起(容易导致死锁);

 

如下情况,处于阻塞状态的线程重新进入就绪状态:

  sleep方法超过了时间;

  调用的阻塞IO方法返回;

  成功取得同步监视器;

  等待某个通知,其他线程发出了通知;

  处于挂起状态的线程 被 调用了resume;

 

死亡状态

如下情况,进入死亡状态:

  run方法执行结束;

  线程抛出一个Exception或Error;

  直接调用stop方法(容易死锁);

 

判断某个线程是否死亡,使用isAlive

  处于 就绪&运行&阻塞 状态时,返回true;

  处于 新建&死亡 状态时,返回false;

 

 

线程控制

join

让一个线程 等待 另一个线程完成;

在当前线程中 调用 其他线程的join,当前线程将一直被阻塞,直到被加入的线程执行完成;

 

sleep

在当前线程中 调用 sleep,当前线程将被一直阻塞,直到过了sleep时间;

 

yield

Thread的static方法,让当前正在执行的线程 暂停 但 不会阻塞(进入就绪状态);

当调用了Thread的yield方法后,只有 与当前线程同等优先级 或 大于当前线程优先级的线程 才有抢占CPU资源的机会;

 

线程的协调运行

Object的Wait()&Notify()&NotifyAll()

这3个方法 必须由 同步监视器 调用

 

wait():

  导致 当前线程等待,直到 其他线程调用该同步监视器的notify()/notifyAll() ;

notify():

  唤醒 在此同步监视器上 等待的单个线程(如果有多个,随机唤醒一个);

notifyAll():

  唤醒 在此同步监视器上 等待的所有线程

 

示例:

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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
public class WaitAndNotifyTest {
 
 
    public static void main(String[] args) {
 
 
        Account account = new Account(0);
 
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                Sender sender = new Sender(account);
                for (int i = 1; i<= 100; i++){
                    sender.getAccount().save(i);
                }
            }
        }, "saver");
 
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                Getter getter = new Getter(account);
                for (int i = 1; i<= 100; i++){
                    getter.getAccount().get(i);
                }
            }
        }, "getter1");
 
        t1.start();
        t2.start();
    }
     
    public static class Sender{
 
        Account account;
        Sender(Account account){
            this.account = account;
        }
 
        public Account getAccount() {
            return account;
        }
 
        public void setAccount(Account account) {
            this.account = account;
        }
    }
 
    public static class Getter{
        Account account;
        Getter(Account account){
            this.account = account;
        }
 
        public Account getAccount() {
            return account;
        }
 
        public void setAccount(Account account) {
            this.account = account;
        }
    }
 
 
    public static class Account{
        private Integer ye;
        private boolean isHave = false;
        Account(Integer ye){
            this.ye = ye;
        }
 
        public Integer getYe() {
            return ye;
        }
 
        public void setYe(Integer ye) {
            this.ye = ye;
        }
 
        public void setHave(boolean have) {
            isHave = have;
        }
 
        public boolean isHave() {
            return isHave;
        }
 
        public synchronized void save(Integer ye){
 
            try {
                if (isHave){
                    this.wait();
                }
                System.out.println(Thread.currentThread().getName() + " save "+ ye);
                this.ye += ye;
                System.out.println(Thread.currentThread().getName() + " save end ye : "+ ye);
                isHave = true;
                this.notifyAll();
            }catch (Exception e){
                e.printStackTrace();
            }
 
        }
 
        public synchronized void get(Integer ye){
            try {
                if (!isHave){
                    this.wait();
                }
                System.out.println(Thread.currentThread().getName() + " get "+ ye);
                this.ye -= ye;
                System.out.println(Thread.currentThread().getName() + " get end ye : "+ ye);
                isHave = false;
                this.notifyAll();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
 
}

  

使用条件变量控制协调

使用Lock保证同步,因为不存在隐式的 同步监视器对象,不能使用wait/notify/notifyAll;

Java提供了Condition来保持协调

  使得到Lock 但 无法继续执行的线程 释放Lock;

  唤醒其他处于等待的线程;

 

Condition对象 被绑定到 Lock对象上;

获得特定Lock对象的Condition对象,使用lock对象的newCondition();

 

Lock替代了 synchronized的同步方法/同步代码块,Condition替代了 同步监视器

 

Condition提供的方法

  await():

    导致当前线程等待,直到 其他线程调用该Condition的singal()/singalAll();

  singal():

    唤醒在此Lock上等待的单个线程(随机唤醒其中一个等待的线程);

  singalAll():

    唤醒在此Lock上等待的所有线程;    

 

示例:

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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
public class LockConditionTest {
 
    public static void main(String[] args) {
        Account account = new Account(0);
 
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                Sender sender = new Sender(account);
                for (int i = 1; i<= 100; i++){
                    sender.getAccount().save(i);
                }
            }
        }, "saver");
 
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                Getter getter = new Getter(account);
                for (int i = 1; i<= 100; i++){
                    getter.getAccount().get(i);
                }
            }
        }, "getter1");
 
        t1.start();
        t2.start();
    }
 
    public static class Sender{
 
        Account account;
        Sender(Account account){
            this.account = account;
        }
 
        public Account getAccount() {
            return account;
        }
 
        public void setAccount(Account account) {
            this.account = account;
        }
    }
 
    public static class Getter{
        Account account;
        Getter(Account account){
            this.account = account;
        }
 
        public Account getAccount() {
            return account;
        }
 
        public void setAccount(Account account) {
            this.account = account;
        }
    }
 
 
    public static class Account{
        private Integer ye;
        private boolean isHave = false;
        private final Lock lock = new ReentrantLock();
        private final Condition condition = lock.newCondition();
 
        Account(Integer ye){
            this.ye = ye;
        }
 
        public Integer getYe() {
            return ye;
        }
 
        public void setYe(Integer ye) {
            this.ye = ye;
        }
 
        public void setHave(boolean have) {
            isHave = have;
        }
 
        public boolean isHave() {
            return isHave;
        }
 
        public void save(Integer ye){
            lock.lock();
            try {
                if (isHave){
                    condition.await();
                }
                System.out.println(Thread.currentThread().getName() + " save "+ ye);
                this.ye += ye;
                System.out.println(Thread.currentThread().getName() + " save end ye : "+ ye);
                isHave = true;
                condition.signalAll();
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
 
        }
 
        public void get(Integer ye){
            lock.lock();
            try {
                if (!isHave){
                    condition.await();
                }
                System.out.println(Thread.currentThread().getName() + " get "+ ye);
                this.ye -= ye;
                System.out.println(Thread.currentThread().getName() + " get end ye : "+ ye);
                isHave = false;
                condition.signalAll();
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
        }
    }
}

  

    

 

posted on   anpeiyong  阅读(6)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2019-01-26 Linux---目录结构

导航

< 2025年3月 >
23 24 25 26 27 28 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 1 2 3 4 5
点击右上角即可分享
微信分享提示