Simple to use Java thread lifecycle and locks

This article describes the life cycle of java thread, several methods Synchronized simple to use.

Thread Life Cycle

  • The initial state (New)

    After New Thread,  

  • Ready state (Ready)

    Cpu get to represent the execution time slice, that is, the implementation of the right to cpu, the waiting begins.  

  • Operating status (Runable)

    After performing the start, began to run.  

  • Blocked (Blocked)

    Synchronized entering the critical region or critical section Lock, and waiting to acquire a monitor (monitor) lock, the thread will enter the synchronization queue (SynchronizedQueue) in.  

  • Wait state: (Waiting)

    Performing await (), wait (), jion (), LockSupport.park () method enters a wait state;  

  • Wait Timeout state

    In the execution Object.await (time), Object.wait (time), Object.sellp (time), LockSupport.parkUntil, lockSupport.parkNanos into the state waiting for the timeout.  

  • Termination state

    The thread is finished or performed Thread.interrupt () / Thread.stop (), Thread.stop used () is not recommended because Thread.stop direct forcibly end, will not release resources ;

  • With pictures

Lock a few simple methods

  • wait 和 notify/notifyAll

    Explanation

    wait: The thread state set 'wait state' , into the waiting queue. Notify / notifyAll: Notify a thread into the random wake up 'the synchronous queue' , notifyAll awaken all the thread into the wait monitor lock 'synchronous queue', waiting for the monitor lock acquire and resumes execution.

    Tip **: ** wait, notify / notifyAll need in the acquired monitor (monitor) before they can operate.

    Code
    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...
    复制代码
  • await,signal/signalAll

    Explanation

    await, signal / signalAll Lock Condition method is a method, semantic and Object of wait, notify / notifyAll are identical.

    Code
    /**
     * @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被唤醒了
    复制代码
  • Join 和 Join(time)

    Explanation

    Waiting thread calls Join the execution is completed before proceeding or wait longer than the timeout period to continue ;

    Code
    /**
     * @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
    复制代码
  • yield

    Explanation

    The core yeid method is to let the cpu time slice , that is, cpu executive power , the thread directly into the ready state , the thread scheduler will be performed ready queue to obtain a thread with the highest priority thread from the thread, of course, also possible to directly go just to make a cpu thread execution right, proceed yield subsequent code.

    Code
    /**
     * @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
    复制代码
  • interrupt and stop

    Explanation

    interrupt and stop represents an interrupt threads, except that interrupt will free up resources and will not stop, will not interrupt immediately interrupted; you have to say something isInterrupted said interrupt method, he is judged thread interrupt flag, if thread A thread execution method B interrupt, thread B can also use the method to judge their own isInterrupted interrupt flag in its own thread.   Note: When using interrupt method, if the thread sleep wait wait (time) state, throws an exception InterruptedException clears interrupt flag isInterrupted acquisition method, not vice versa

    Code
    /**
     * @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
    复制代码

    Blog address: lantaoblog.site

Guess you like

Origin juejin.im/post/5d53d0de6fb9a06af92b9ac2