Javaスレッドのライフサイクルとロックを使用するのは簡単

この記事では、Javaスレッドのライフサイクルは、いくつかの方法が使用するのは簡単同期について説明します。

スレッドのライフサイクル

  • 初期状態(新)

    新しいスレッドの後、  

  • レディ状態(レディ)

    CPUは、CPUへの権利の実装である実行時間スライスを、表現するために取得し、待機が開始されます。  

  • 動作状態(Runable)

    スタートを実行した後、実行し始めました。  

  • ブロックされた(ブロック)

    クリティカル領域またはクリティカルセクションのロックを入力すると、モニター(モニター)ロックを取得するために待機している同期化、スレッドは、同期キュー(SynchronizedQueue)を入力します。  

  • 待ち状態:(待機)

    await()を実行し、()、jion()、LockSupport.park()メソッドは、待機状態に入る待ちます。  

  • タイムアウト待ち状態

    実行状態にObject.await(時間)、はObject.wait(時間)、Object.sellp(時間)、LockSupport.parkUntil、lockSupport.parkNanosタイムアウトを待っていますで。  

  • 終了状態

    スレッドが終了または/ Thread.stopの()は、Thread.interrupt()が実行される Thread.stopのは、 (使用)Thread.stopの直接ので推奨されない強制的に終了し、リソースを解放しないであろうが

  • 写真付き

いくつかの簡単な方法をロック

  • 通知和待つ/のnotifyAll

    説明

    待つ:スレッドの状態を設定「状態を待つ」待機キューに。:/のnotifyAll通知ランダムウェイクアップにスレッドを通知する「同期キュー」モニターロックの獲得を待って、待機モニターロック「同期キュー」にすべてのスレッドを目覚めさせるのnotifyAll、および実行を再開します。

    ヒント**:**それらが動作する前に取得した監視(モニター)に必要なのnotifyAll /通知し、待ちます。

    コード
    public class WaitAndNotifyTest {
    
        private static Object obj = new Object();
    
        public static void main(String[] args) {
            // 创建线程 thread1
            Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        System.out.println(Thread.currentThread().getName() + "   begin wait...");
                        synchronized (obj) {
                            obj.wait();
                        }
                        System.out.println(Thread.currentThread().getName() + "   end wait...");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }, "thread1");
    
            // 创建线程 thread2
            Thread thread2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        System.out.println(Thread.currentThread().getName() + "   begin wait...");
                        synchronized (obj) {
                            obj.wait();
                        }
                        System.out.println(Thread.currentThread().getName() + "   end wait...");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }, "thread2");
    
    
    
            // 启动
            thread1.start();
            thread2.start();
    
            try {
                // 睡眠一秒
                Thread.sleep(1000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            // 下面我们加上 obj.notify() 就会先输出 begin wait  然后sellp 10秒,执行obj.notify() 唤醒 thread1 线程 , 输出end wait
            // obj 上可能会存在wait 多个线程, notify唤醒是随机的,不一定能唤醒哪一个线程
            // 如果调用 notify 的线程未获取 对象锁,在调用 notify 的时候会抛出 java.lang.IllegalMonitorStateException 异常
            synchronized (obj) {
                // 唤醒 使用呢 obj 调用 wait 方法的其中一个线程 (随机)
                obj.notify();
                // 唤醒 使用呢 obj 调用 wait 方法的所有线程
                obj.notifyAll();
            }
        }
    }
    复制代码
    执行结果:
    thread2   begin wait...
    thread1   begin wait...
    thread1   end wait...
    thread2   end wait...
    复制代码
  • 信号/ signalAll、待ちます

    説明

    待って、信号/ signalAllロック条件法は、意味や待ち時間のオブジェクト、メソッドで、通知/のnotifyAll同じです。

    コード
    /**
     * @Auther: lantao
     * @Date: 2019-04-15 14:49
     * @Company:
     * @maill:
     * @Description: Condition 条件 有 singal signalAll 和 await 方法 和Object 的 notify notifyAll 和 wait 是一个意思同样会释放锁  执行singal和notify的时候也需要在等待获取锁
     */
            public class LockCondition {
    
                public static ReentrantLock lock = new ReentrantLock();
    
                public static Condition a = lock.newCondition();
    
                public static void main(String[] args) throws InterruptedException {
                    Runnable runnable = () -> {
                        try {
                            lock.lock();
                            System.out.println(Thread.currentThread().getName());
                            System.out.println("1");
                            a.await();
    
                            System.out.println(Thread.currentThread().getName() + "被唤醒了");
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }finally {
                            lock.unlock();
                        }
                    };
    
                    Runnable runnable1 = () -> {
                        try {
                            lock.lock();
                            System.out.println("线程" +Thread.currentThread().getName() + "开始执行sinal");
                            a.signalAll();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }finally {
                            lock.unlock();
                        }
                    };
    
                    new Thread(runnable,"Thread1").start();
                    new Thread(runnable,"Thread2").start();
                    Thread.sleep(100);
                    new Thread(runnable1,"Thread3").start();
                }
            }
    复制代码
    执行结果:
    Thread1
    Thread2
    线程Thread3开始执行sinal
    Thread1被唤醒了
    Thread2被唤醒了
    复制代码
  • (時間)参加和参加

    説明

    待機中のスレッドの呼び出しが参加し、実行が完了する先に進む前に、または継続するタイムアウト期間より長く待ちます

    コード
    /**
     * @Auther: lantao
     * @Date:
     * @Company:
     * @maill:
     * @Description: Join 核心是等待指定线程运行完后再继续运行  Join(time) 就是等待线程执行的一个超时时间 超过了就继续执行了
     */
            public class JoinTest {
                public static void main(String[] args) throws InterruptedException {
                    Thread thread1 = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            System.out.println("1");
                            try {
                                Thread.sleep(2000L);
                                System.out.println("正常完成");
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            System.out.println("2");
                        }
                    });
    
                    thread1.start();
    
                    // 执行 jion 等待线程 thread1 执行完后再继续执行
                    thread1.join();
    //        thread1.join(1000);
    
                    // 这样最终执行的顺序是 1 2 3  如果不增加 thread1.join() 结果可能是 312 也可能是 132
                    // Join 核心是等待指定线程运行完后再继续运行
                    System.out.println("3");
                }
            }
    复制代码
    执行结果:
    1
    正常完成
    2
    3
    复制代码
  • 産出

    説明

    コアyeid方法は、することですCPUタイムスライスを聞かせているが、ある、CPUの執行力、直接にスレッド実行可能状態、スレッドスケジューラは直接移動することも、当然のことながら、スレッドから最も優先度の高いスレッドとスレッドを得ることが可能とレディキューを実行されますただ、CPUスレッドの実行権を作るために、それ以降のコードをもたらす進めます。

    コード
    /**
     * @Auther: lantao
     * @Date: 2019-03-25 17:20
     * @Company:
     * @maill:
     * @Description:
     */
            public class YieldTest {
    
                private static Object obj = new Object();
    
    
                public static void main(String[] args) {
                    Thread thread1 = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            for (int i = 0; i <= 5; i++) {
    
                                if (0 / 5 == i) {
                                    System.out.println(Thread.currentThread().getName() + "   开始执行 yield ");
                                    Thread.yield();
                                    System.out.println("trhead1");
                                }
                            }
                        }
                    }, "thread1");
                    Thread thread2 = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            for (int i = 0; i <= 5; i++) {
                                if (0 / 5 == i) {
                                    System.out.println(Thread.currentThread().getName() + "   开始执行 yield ");
                                    Thread.yield();
                                    System.out.println("trhead2");
                                }
                            }
                        }
                    }, "thread2");
                    Thread thread3 = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            for (int i = 0; i <= 5; i++) {
                                if (0 / 5 == i) {
                                    System.out.println(Thread.currentThread().getName() + "   开始执行 yield ");
                                    Thread.yield();
                                    System.out.println("trhead3");
                                }
                            }
    
                        }
                    }, "thread3");
    
                    // 执行三个线程, 正常当运行到yield 是 就会让出cpu执行权,线程到 就绪状态,线程调度器会从 线程就绪队列里获取一个线程优先级最高的线程来执行,
                    // 当然也有可能直接会去到刚刚让出cpu的线程,继续执行yield 后续的代码
                    thread1.start();
                    thread3.start();
                    thread2.start();
    
                }
            }
    复制代码
    执行结果:
    
    thread1   开始执行 yield
    thread2   开始执行 yield
    thread3   开始执行 yield
            trhead2
    trhead1
    trhead3
    复制代码
  • 中断と停止

    説明

    すぐに中断中断しません、中断及びその割り込みがリソースを解放し、停止しません除いて停止は、割り込みスレッドを表し、あなたがスレッドの実行を通す場合は、何かisInterruptedを、彼は、スレッドの割り込みフラグを判断された割り込み方法と言わざるを得ない方法B割り込みは、スレッドBは、独自のスレッドで独自のisInterruptedを割り込みフラグを判断する方法を使用することができます。   注:割り込み方式を使用する場合、スレッドスリープ待機待ち時間(時間)状態は、例外InterruptedExceptionあるがないその逆、割り込みフラグisInterruptedを取得方法をクリアした場合にスロー

    コード
    /**
     * @Auther: lantao
     * @Date: 2019-04-17 17:18
     * @Company:
     * @maill:
     * @Description: 在使用 interrupt方法是,如果线程咋sleep wait wait(time) 在抛出InterruptedException异常后会 清除 isInterrupted 方法获取的标志位 其他则不会
     */
            public class InterruptTest {
                public static void main(String[] args) throws InterruptedException {
                    Thread thread1 = new Thread(() -> {
                        while (true) {}
                    }, "循环线程");
    
                    Thread thread2 = new Thread(() -> {
                        while (true) {
                            try {
                                Thread.sleep(200);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }, "睡眠线程");
    
                    Thread thread3 = new Thread(() -> {
                        Object o = new Object();
                        while (true) {
                            synchronized (o){
                                try {
                                    o.wait();
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }, "等待线程");
    
                    thread1.start();
                    thread2.start();
                    thread3.start();
                    Thread.sleep(500);
    
                    thread1.interrupt();
                    thread2.interrupt();
                    thread3.interrupt();
                    Thread.sleep(500);
                    System.out.println("循环线程isInteryupt is " + thread1.isInterrupted());
                    System.out.println("睡眠线程isInteryupt is " + thread2.isInterrupted());
                    System.out.println("等待线程isInteryupt is " + thread3.isInterrupted());
    
    
                }
            }
    复制代码
    执行结果:
    
    java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at com.com.concurrenncy.InterruptTest.lambda$main$1(InterruptTest.java:20)
    at java.lang.Thread.run(Thread.java:748)
    java.lang.InterruptedException
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:502)
    at com.com.concurrenncy.InterruptTest.lambda$main$2(InterruptTest.java:32)
    at java.lang.Thread.run(Thread.java:748)
    循环线程isInteryupt is true
    睡眠线程isInteryupt is false
    等待线程isInteryupt is false
    复制代码

    ブログのアドレス:lantaoblog.site

おすすめ

転載: juejin.im/post/5d53d0de6fb9a06af92b9ac2