zoukankan      html  css  js  c++  java
  • join()、park()、yield()会不会释放当前线程持有的锁?

    stop()、suspend()、Thread.sleep()都不会释放线程所持有的锁。但join()、park()、yield()会不会释放当前线程持有的锁?下面通过一些实例来验证一下

    代码如下

    import java.util.Date;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.locks.LockSupport;
    
    public class ThreadLockTest {
    
        public static void main(String[] args) throws InterruptedException {
            // yieldTest(10);
            // parkTest();
            // joinTest();
        }
    
        /**
         * 测试yield会不会释放锁:yield调用的是本地方法,建议seconds设置大一些结果更明显
         * 结论:yield不会释放线程持有的锁
         *
         * @param seconds
         */
        private static void yieldTest(int seconds) {
            String lock = "lock";
    
            //首先执行并获得锁
            Thread preThread = new Thread() {
                @Override
                public void run() {
                    synchronized (lock) {
                        log("=============获取了锁==============");
                        long start = System.currentTimeMillis();
                        while (true) {
                            //将让出当前线程的执行权,线程状态由RUNNING ----> RUNNABLE
                            log(".........yield()被调用");
                            yield();
                            long currentTimeMillis = System.currentTimeMillis();
                            if (currentTimeMillis - start >= 1000 * seconds) {
                                log("---------释放锁并结束线程");
                                break;
                            }
                        }
                    }
                }
            };
            preThread.setName("preThread");
            preThread.start();
    
            //在preThread之后执行的线程
            new Thread(() -> {
                try {
                    Thread.sleep(1000);
                    synchronized (lock) {
                        log("=============获取了锁==============");
                    }
                } catch (InterruptedException e) {
                }
    
    
            },"postThread").start();
        }
    
        /**
         * 测试park会不会释放锁
         * 结论:park不会释放线程持有的锁
         */
        private static void parkTest() throws InterruptedException {
            String lock = "lock";
    
            ////首先执行并获得锁
            Thread preThread = new Thread(() -> {
                log("运行....");
                synchronized (lock) {
                    log("=============获取了锁==============");
                    log(".........park被调用");
                    //没被唤醒就会一直等待
                    LockSupport.park();
                    log("被unpark.....");
                }
            },"preThread");
    
            preThread.start();
    
            //在preThread之后执行的线程
            new Thread(() -> {
                try {
                    log("运行....");
                    Thread.sleep(100);
                    log("+++++++++等待获取锁");
                    synchronized (lock) {
                        log("=============获取了锁==============");
                    }
                } catch (InterruptedException e) {
                }
    
            },"postThread").start();
    
            //主线程等待10秒,然后唤醒preThread线程
            TimeUnit.SECONDS.sleep(10);
            log("主线程唤醒unpark....");
            LockSupport.unpark(preThread);
        }
    
        /**
         * 测试 join 会不会释放锁
         * 结论:join不会释放线程持有的锁
         */
        private static void joinTest() {
            String lock = "lock";
    
            //任务线程
            Thread taskThread = new Thread(() -> {
                log("*********任务线程启动!");
                long currentTimeMillis = System.currentTimeMillis();
                while (true) {
                    //执行任务需要10秒
                    if (System.currentTimeMillis() - currentTimeMillis > 10000) {
                        log("任务执行完毕!*********");
                        return;
                    }
                }
            },"taskthread");
    
            //首先执行并获得锁
            Thread preThread = new Thread(() -> {
                log("运行....");
                try {
                    synchronized (lock) {
                        log("=============获取了锁==============");
                        //启动线程2并一直等待线程taskThread完成
                        taskThread.start();
                        log(".........join被调用");
                        taskThread.join();
                        log("---------join执行完毕");
                    }
                } catch (InterruptedException e) {
                }
    
            },"preThread");
            preThread.start();
    
            //在preThread之后执行的线程
            Thread postThread = new Thread(() -> {
                try {
                    log("运行....");
                    Thread.sleep(1000);
                    log("+++++++++等待获取锁");
                    synchronized (lock) {
                        log("=============获取了锁==============");
                    }
                } catch (InterruptedException e) {
                }
    
            },"postThread");
            postThread.start();
    
        }
    
    
        /**
         * 日志打印
         *
         * @param msg
         */
        private static void log(String msg) {
            System.out.println(new Date() + " " + Thread.currentThread().getName() + " " + msg);
        }
    }

    运行结果可以自定粘贴运行,结论如下

    join()、park()、yield()不会释放当前线程持有的锁!

  • 相关阅读:
    HTML基础(一)基本语法知识
    本地方法接口
    本地方法栈
    虚拟机栈相关的问题
    栈帧的内部结构--一些附加信息
    基于角色的权限控制设计
    SpringBoot普通消息队列线程池配置
    栈帧的内部结构--动态返回地址(Return Address)
    栈帧的内部结构--动态链接 (Dynamic Linking)
    栈帧的内部结构--操作数栈(Opreand Stack)
  • 原文地址:https://www.cnblogs.com/kitor/p/14724244.html
Copyright © 2011-2022 走看看