Javaの学習ログ(XII):スレッド、ケースを覚ますのを待っています

継続的に更新JavaEEの学習ログ---->必見!JavaEEの学習ルート(記事要約)

スレッド状態

APIのjava.lang.Thread.Stateこの列挙には6つのスレッドの状態を考えると:

スレッド状態 状態につながる状態の発生
NEW(新) ただ、スレッドを作成しますが、起動しませんでした。いいえstartメソッドが呼び出されません。
Runnableを(実行) スレッドの状態は、Java仮想マシンを実行することができて、自分のコードを実行することができる、または、オペレーティングシステムのプロセッサに依存しないことがあります。
ブロックされた(ロックブロック) スレッド試みがターゲットロックを取得するときにオブジェクトの他のスレッドは、スレッドがブロックされた状態になるが、ロックが保持され、スレッドがロックを保持している場合、スレッドは実行可能状態になるであろう。
待機中(無期限に待機) 別のスレッドが待機(ウェイクアップ)アクションを実行している間、スレッドは、スレッドが待機状態になります。それは自動的にウェイクアップされていないこの状態に入った後、目を覚ますことができるように、別の呼び出しが通知スレッドまたはのnotifyAllメソッドを待たなければなりません。
時限待機(タイミング待ち) 待機状態では、パラメータのタイムアウトいくつかの方法がありますが、彼らは、コール時限待機状態になります。タイムアウトの期限が切れるか、ウェイクアップ通知を受信するまでこの状態が維持されます。タイムアウトパラメータを持つ一般的な方法のThread.sleep、はObject.waitです。
Teminated(終了) runメソッドは、通常と死終了しているため、または中断runメソッドと死のない撮影がないので。

ここに画像を挿入説明

待っていると、ウェイクアップケース(ケース包子プルトニウム)

そして、ウェイクアップを待っている:間の通信スレッド
Objectクラスのメソッド

  • void wait() それは目覚めされるため、現在のスレッドを待機させ、通常、通知または中断。
  • void notify()このオブジェクトのモニター(目覚めるオブジェクトロック待機中に単一のスレッドを)。

注意:

  1. wait和notify方法必须由锁对象调用(必须是同个锁对象
    锁对象–>wait() 锁对象–>notify()
  2. wait和notify方法一般写在同步中

案例:包子铺案例

需求
两大线程:设线程A(包子铺),执行生产包子的动作。线程B(吃货),执行吃包子的操作

共享资源:包子

执行动作:生产一个包子,吃一个包子

分析
包子的状态进行分析
没有包子:吃货线程唤醒包子铺线程—>吃货线程等待—>包子铺线程做包子—>包子铺做好包子—>修改包子的状态—>有包子
有包子:包子铺唤醒吃货线程—>包子铺线程等待—>吃货吃包子—>修改包子的状态—>没有包子
…(循环)

代码实现:

资源类:包子,其中有皮,陷,包子的状态

public class BaoZi {
    String pi;
    String xian;
    //包子状态,初始值为false,没有包子
    boolean flag = false;
}

包子铺类:是一个线程类,线程任务:生产包子

对包子的状态进行判断:
true:有包子
        包子铺线程调用wait等待
false:没有包子
        包子铺线程生产包子
        生产x皮x陷的包子
        生产包子花费3秒
        生产完包子,修改包子状态为true
        包子铺线程唤醒吃货线程,吃包子

注意:

  1. 生产包子和吃包子,只能有一个在执行,需要使用同步技术
  2. 同步技术需要使用锁对象,可以使用包子对象
    在成员位置创建一个包子对象
    使用构造方法为包子变量赋值
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
    吃货线程唤醒包子铺线程,做包子

注意:

  1. 生产包子和吃包子,只能有一个在执行,需要使用同步技术
  2. 同步技术需要使用锁对象,可以使用包子对象
    在成员位置创建一个包子对象
    使用构造方法为包子变量赋值
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();
    }
}

运行结果:

包子铺正在生产薄皮玉米鲜肉的包子!
包子铺已经生产好薄皮玉米鲜肉的包子!
吃货正在吃薄皮玉米鲜肉的包子!
吃货已经吃完了薄皮玉米鲜肉的包子!包子铺赶紧生产包子!
-----------------------
包子铺正在生产薄皮玉米鲜肉的包子!
包子铺已经生产好薄皮玉米鲜肉的包子!
吃货正在吃薄皮玉米鲜肉的包子!
吃货已经吃完了薄皮玉米鲜肉的包子!包子铺赶紧生产包子!
-----------------------
...
公開された16元の記事 ウォン称賛17 ビュー1834

おすすめ

転載: blog.csdn.net/Sakuraaaaaaa/article/details/104234964