継続的に更新JavaEEの学習ログ---->必見!JavaEEの学習ルート(記事要約)
Javaの学習ログ(XII)
スレッド状態
APIのjava.lang.Thread.Stateこの列挙には6つのスレッドの状態を考えると:
スレッド状態 | 状態につながる状態の発生 |
---|---|
NEW(新) | ただ、スレッドを作成しますが、起動しませんでした。いいえstartメソッドが呼び出されません。 |
Runnableを(実行) | スレッドの状態は、Java仮想マシンを実行することができて、自分のコードを実行することができる、または、オペレーティングシステムのプロセッサに依存しないことがあります。 |
ブロックされた(ロックブロック) | スレッド試みがターゲットロックを取得するときにオブジェクトの他のスレッドは、スレッドがブロックされた状態になるが、ロックが保持され、スレッドがロックを保持している場合、スレッドは実行可能状態になるであろう。 |
待機中(無期限に待機) | 別のスレッドが待機(ウェイクアップ)アクションを実行している間、スレッドは、スレッドが待機状態になります。それは自動的にウェイクアップされていないこの状態に入った後、目を覚ますことができるように、別の呼び出しが通知スレッドまたはのnotifyAllメソッドを待たなければなりません。 |
時限待機(タイミング待ち) | 待機状態では、パラメータのタイムアウトいくつかの方法がありますが、彼らは、コール時限待機状態になります。タイムアウトの期限が切れるか、ウェイクアップ通知を受信するまでこの状態が維持されます。タイムアウトパラメータを持つ一般的な方法のThread.sleep、はObject.waitです。 |
Teminated(終了) | runメソッドは、通常と死終了しているため、または中断runメソッドと死のない撮影がないので。 |
待っていると、ウェイクアップケース(ケース包子プルトニウム)
そして、ウェイクアップを待っている:間の通信スレッド
Objectクラスのメソッド
void wait()
それは目覚めされるため、現在のスレッドを待機させ、通常、通知または中断。void notify()
このオブジェクトのモニター(目覚めるオブジェクトロック待機中に単一のスレッドを)。
注意:
- wait和notify方法必须由锁对象调用(必须是同个锁对象)
锁对象–>wait() 锁对象–>notify() - wait和notify方法一般写在同步中
案例:包子铺案例
需求:
两大线程:设线程A(包子铺),执行生产包子的动作。线程B(吃货),执行吃包子的操作
共享资源:包子
执行动作:生产一个包子,吃一个包子
分析:
对包子的状态进行分析
没有包子:吃货线程唤醒包子铺线程—>吃货线程等待—>包子铺线程做包子—>包子铺做好包子—>修改包子的状态—>有包子
有包子:包子铺唤醒吃货线程—>包子铺线程等待—>吃货吃包子—>修改包子的状态—>没有包子
…(循环)
代码实现:
资源类:包子,其中有皮,陷,包子的状态
public class BaoZi {
String pi;
String xian;
//包子状态,初始值为false,没有包子
boolean flag = false;
}
包子铺类:是一个线程类,线程任务:生产包子
对包子的状态进行判断:
true:有包子
包子铺线程调用wait等待
false:没有包子
包子铺线程生产包子
生产x皮x陷的包子
生产包子花费3秒
生产完包子,修改包子状态为true
包子铺线程唤醒吃货线程,吃包子
注意:
- 生产包子和吃包子,只能有一个在执行,需要使用同步技术
- 同步技术需要使用锁对象,可以使用包子对象
在成员位置创建一个包子对象
使用构造方法为包子变量赋值
public class BaoZiPu implements Runnable {
//在成员位置创建一个包子对象
BaoZi bz;
//使用构造方法为包子变量赋值
public BaoZiPu(BaoZi bz) {
this.bz = bz;
}
//线程任务:生产包子
@Override
public void run() {
while(true){
/*
1.生产包子和吃包子,只能有一个在执行,需要使用同步技术
2.同步技术需要使用锁对象,可以使用包子对象
*/
synchronized (bz){
//对包子状态进行判断
if(bz.flag==true){
//true:有包子
// 包子铺线程调用wait等待
try {
bz.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//包子铺被吃货唤醒之后执行的代码
//false:没有包子,包子铺线程生产包子
//生产x皮x陷的包子
bz.pi = "薄皮";
bz.xian = "玉米鲜肉";
System.out.println("包子铺正在生产"+bz.pi+bz.xian+"的包子!");
//生产包子花费3秒
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//生产完包子,修改包子状态为true
bz.flag = true;
//包子铺线程唤醒吃货线程,吃包子
bz.notify();
System.out.println("包子铺已经生产好"+bz.pi+bz.xian+"的包子!");
}
}
}
}
吃货类:是一个线程类,线程任务:吃包子
对包子的状态进行判断:
false:没有包子
吃货线程调用wait等待
true:有包子
吃货线程开始吃包子
打印吃x皮x陷的包子
吃完包子,修改包子的状态为false
吃货线程唤醒包子铺线程,做包子
注意:
- 生产包子和吃包子,只能有一个在执行,需要使用同步技术
- 同步技术需要使用锁对象,可以使用包子对象
在成员位置创建一个包子对象
使用构造方法为包子变量赋值
public class ChiHuo implements Runnable{
//在成员位置创建一个包子对象
BaoZi bz;
//使用构造方法为包子变量赋值
public ChiHuo(BaoZi bz) {
this.bz = bz;
}
//线程任务:吃包子
@Override
public void run() {
while (true){
/*
1.生产包子和吃包子,只能有一个在执行,需要使用同步技术
2.同步技术需要使用锁对象,可以使用包子对象
*/
synchronized (bz){
//对包子的状态进行判断
// false:没有包子
if (bz.flag==false){
//吃货线程调用wait等待
try {
bz.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/*
吃货线程被包子铺线程唤醒之后执行的代码
*/
//true:有包子,吃货线程开始吃包子
//打印吃x皮x陷的包子
System.out.println("吃货正在吃"+bz.pi+bz.xian+"的包子!");
//吃完包子,修改包子的状态为false
bz.flag = false;
//吃货线程唤醒包子铺线程,做包子
bz.notify();
System.out.println("吃货已经吃完了"+bz.pi+bz.xian+"的包子!包子铺赶紧生产包子!");
System.out.println("-----------------------");
}
}
}
}
测试类:
创建一个包子对象
创建一个包子铺线程,生产包子
创建一个吃货线程,吃包子
public class Demo01 {
public static void main(String[] args) {
//创建一个包子对象
BaoZi bz = new BaoZi();
//创建一个包子铺线程,生产包子
new Thread(new BaoZiPu(bz)).start();
//创建一个吃货线程,吃包子
new Thread(new ChiHuo(bz)).start();
}
}
运行结果:
包子铺正在生产薄皮玉米鲜肉的包子!
包子铺已经生产好薄皮玉米鲜肉的包子!
吃货正在吃薄皮玉米鲜肉的包子!
吃货已经吃完了薄皮玉米鲜肉的包子!包子铺赶紧生产包子!
-----------------------
包子铺正在生产薄皮玉米鲜肉的包子!
包子铺已经生产好薄皮玉米鲜肉的包子!
吃货正在吃薄皮玉米鲜肉的包子!
吃货已经吃完了薄皮玉米鲜肉的包子!包子铺赶紧生产包子!
-----------------------
...