zoukankan      html  css  js  c++  java
  • Java多线程系列二——Thread类的方法

    Thread实现Runnable接口并实现了大量实用的方法

    public static native void yield();

    此方法释放CPU,但并不释放已获得的锁,其它就绪的线程将可能得到执行机会,它自己也有可能再次得到执行机会

    public static native void sleep(long millis) throws InterruptedException;

    此方法释放CPU,但并不释放已获得的锁,其它就绪的线程将得到执行机会,在休眠时间结束后,当前线程继续执行

    public final void join() throws InterruptedException;

    一旦调用后宿主线程将阻塞,待当前线程结束后继续

    public final synchronized void join(long millis)throws InterruptedException;

    一旦调用后宿主线程将阻塞,待millis时间结束后继续

    public void interrupt();

    中断线程

    public final void setDaemon(boolean on);

    on=true表示线程标记为守护线程(例如GC线程),若正在运行的所有线程都是守护线程,JVM将退出

    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.concurrent.atomic.AtomicInteger;
    
    import org.junit.Assert;
    import org.junit.Test;
    
    /**
     * @Description: 测试Thread的方法
     */
    public class ThreadMethodsTest {
        static String SLEEP = "sleep";
        static String YIELD = "yield";
        static String JOIN = "join";
        private Map<String, ThreadMethodEnum> map = new ConcurrentHashMap<>();
    
        class TheadSleep implements Runnable {
            private int millis;
    
            public TheadSleep(int millis) {
                this.millis = millis;
            }
    
            @Override
            public void run() {
                long threadId = Thread.currentThread().getId();
                ThreadMethodEnum sleep = ThreadMethodEnum.SLEEP;
                sleep.init(threadId);
                try {
                    Thread.sleep(millis);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                sleep.stop();
                map.put(sleep.getMethod(), sleep);
            }
        }
    
        class TheadYield implements Runnable {
            @Override
            public void run() {
                long threadId = Thread.currentThread().getId();
                ThreadMethodEnum yield = ThreadMethodEnum.YIELD;
                yield.init(threadId);
                Thread.yield();
                yield.stop();
                map.put(yield.getMethod(), yield);
            }
        }
    
        class TheadJoin implements Runnable {
            private Thread thread;
            private int millis = 0;
    
            public TheadJoin(Thread thread) {
                this.thread = thread;
            }
    
            public TheadJoin(Thread thread, int millis) {
                this.thread = thread;
                this.millis = millis;
            }
    
            @Override
            public void run() {
                try {
                    long threadId = Thread.currentThread().getId();
                    ThreadMethodEnum join = ThreadMethodEnum.JOIN;
                    join.init(threadId);
                    if (millis > 0) {
                        this.thread.join(millis);
                    } else {
                        this.thread.join();
                    }
                    join.stop();
                    map.put(join.getMethod(), join);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
        final AtomicInteger interruptCount = new AtomicInteger(0);
        final int interruptIndex = 100;
    
        class ThreadInterrupt extends Thread {
            @Override
            public void run() {
                while (!isInterrupted()) {
                    interruptCount.incrementAndGet();
                    if (interruptCount.intValue() == interruptIndex) {
                        interrupt();
                    }
                }
            }
        }
    
        @Test
        public void testSleep() throws InterruptedException {
            int millis = 1000;
            Thread sleep = new Thread(new TheadSleep(millis));
            sleep.start();
            sleep.join();
            ThreadMethodEnum tme = map.get(SLEEP);
            // 预期sleep时间与millis相近
            Assert.assertEquals(1, Math.round((tme.getStopTimeMillis() - tme.getStartTimeMillis()) * 1.0 / millis));
        }
    
        @Test
        public void testYield() throws InterruptedException {
            Thread yield = new Thread(new TheadYield());
            yield.start();
            yield.join();
            ThreadMethodEnum tme = map.get(YIELD);
            // 预期yield消耗时间几乎为0
            Assert.assertEquals(1, Math.round(tme.getStartTimeMillis() * 1.0 / tme.getStopTimeMillis()));
        }
    
        @Test
        public void testJoin() throws InterruptedException {
            int millis = 1000;
            Thread sleep = new Thread(new TheadSleep(millis));
            sleep.start();
            Thread join = new Thread(new TheadJoin(sleep));
            join.start();
            join.join();
            ThreadMethodEnum tme = map.get(SLEEP);
            // 预期sleep时间与millis相近
            Assert.assertEquals(1, Math.round((tme.getStopTimeMillis() - tme.getStartTimeMillis()) * 1.0 / millis));
            tme = map.get(JOIN);
            // 预期join阻塞时间与millis相近
            Assert.assertEquals(1, Math.round((tme.getStopTimeMillis() - tme.getStartTimeMillis()) * 1.0 / millis));
        }
    
        @Test
        public void testJoinMillis() throws InterruptedException {
            int millis = 500;
            Thread sleep = new Thread(new TheadSleep(millis * 2));
            sleep.start();
            Thread join = new Thread(new TheadJoin(sleep, millis));
            join.start();
            join.join();
            ThreadMethodEnum tme = map.get(SLEEP);
            // 预期sleep不能在join阻塞结束前设置,故为null
            Assert.assertTrue(tme == null);
            tme = map.get(JOIN);
            // 预期join阻塞时间与millis相近
            Assert.assertEquals(1, Math.round((tme.getStopTimeMillis() - tme.getStartTimeMillis()) / millis));
        }
    
        @Test
        public void testInterrupt() throws InterruptedException {
            ThreadInterrupt interrupt = new ThreadInterrupt();
            interrupt.start();
            interrupt.join();
            Assert.assertEquals(interruptIndex, interruptCount.intValue());
        }
    }
    
    enum ThreadMethodEnum {
        SLEEP(ThreadMethodsTest.SLEEP) {
            @Override
            public void init(long threadId) {
                super.start(threadId);
            }
        },
        YIELD(ThreadMethodsTest.YIELD) {
            @Override
            public void init(long threadId) {
                super.start(threadId);
            }
        },
        JOIN(ThreadMethodsTest.JOIN) {
            @Override
            public void init(long threadId) {
                super.start(threadId);
            }
        };
        private String method;
        private long threadId;
        private long startTimeMillis;
        private long stopTimeMillis = 0;
    
        private ThreadMethodEnum(String method) {
            this.method = method;
        }
    
        public void stop() {
            this.stopTimeMillis = System.currentTimeMillis();
        }
    
        public String getMethod() {
            return method;
        }
    
        public long getThreadId() {
            return threadId;
        }
    
        public long getStartTimeMillis() {
            return startTimeMillis;
        }
    
        public long getStopTimeMillis() {
            return stopTimeMillis;
        }
    
        private void start(long threadId) {
            this.threadId = threadId;
            this.startTimeMillis = System.currentTimeMillis();
        }
    
        public abstract void init(long threadId);
    }
  • 相关阅读:
    canvas性能优化——离屏渲染
    event.target 和 event.currentTarget 的区别
    Electron 主进程和渲染进程互相通信
    谈谈 JS 垃圾回收机制
    【Vue】Vue中render函数用到的with(this)中with的用法及其优缺点
    Java递归读取文件路径下所有文件名称并保存为Txt文档
    Java读取Excel指定列的数据详细教程和注意事项
    Sybase ASE无响应的又一个情况
    AWR报告导出的过程报ORA-06550异常
    如何借助浏览器Console使用Js进行定位和操作元素
  • 原文地址:https://www.cnblogs.com/hiver/p/7122715.html
Copyright © 2011-2022 走看看