• 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()不会释放当前线程持有的锁!

  • 相关阅读:
    [编织消息框架][设计协议]bit基础
    android studio最简单的包名修改方法
    MySQL之四——浅谈 DML、DDL、DCL的区别
    MySQL之三——SQL优化
    MySQL之二——MySQL缓存机制
    MySQL之一——基础语法详解
    游戏测试相关内容
    第一篇博客
    mybatis中union可以用if判断连接,但是<select>中第一个select语句不能被if判断,因此可以从dual表中查询null来凑齐。union如果使用order by排序,那么只能放在最后一个查询语句的位置,并且不能带表名。
    博客园
  • 原文地址:https://www.cnblogs.com/kitor/p/14724244.html
Copyright © 2020-2023  润新知