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

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

    /*
     * 此方法释放CPU,但并不释放已获得的锁,其它就绪的线程将可能得到执行机会,它自己也有可能再次得到执行机会
     */
    public static native void yield();
    
    /*
     * 此方法释放CPU,但并不释放已获得的锁,其它就绪的线程将得到执行机会,在休眠时间结束后,当前线程继续执行
     */
    public static native void sleep(long millis) throws InterruptedException;
    
    /*
     * 一旦调用后宿主线程将阻塞,待当前线程结束后继续
     */
    public final void join() throws InterruptedException;
    
    /*
     * 一旦调用后宿主线程将阻塞,待当前线程结束后继续
     */
    public final synchronized void join(long millis)throws InterruptedException;
    
    /*
     * 中断线程
     */
    public void interrupt();
    
    /*
     * on=true表示线程标记为守护线程(例如GC线程),若正在运行的所有线程都是守护线程,JVM将退出
     */
    public final void setDaemon(boolean on);

     Java代码:

    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 ThreadSleep implements Runnable {
            private int millis;
            
            public ThreadSleep(int millis) {
                this.millis = millis;
            }
            
            @Override
            public void run() {
                System.out.println("Thread sleep 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 ThreadYield 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 ThreadJoin implements Runnable {
            private Thread thread;
            private int millis = 0;
            
            public ThreadJoin(Thread thread) {
                this.thread = thread;
            }
            
            public ThreadJoin(Thread thread, int millis) {
                this.thread = thread;
                this.millis = millis;
            }
            
            @Override
            public void run() {
                try {
                    System.out.println("Thread join run()...");
                    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 ThreadSleep(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 ThreadYield());
            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 {
            System.out.println("testJoin() ----  start----");
            int millis = 1000;
            Thread sleep = new Thread(new ThreadSleep(millis));
            sleep.setName("Sleep Thread");
            sleep.start();
            Thread join = new Thread(new ThreadJoin(sleep));
            join.setName("Join Thread");
            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));
            System.out.println("testJoin() ----  end----");
        }
        
        @Test
        public void testJoinMillis() throws InterruptedException {
            System.out.println("testJoinMillis() ----  start----");
            int millis = 500;
            Thread sleep = new Thread(new ThreadSleep(millis * 2));
            sleep.setName("Sleep Thread");
            sleep.start();
            Thread join = new Thread(new ThreadJoin(sleep, millis));
            join.setName("Join Thread");
            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));
            System.out.println("testJoinMillis() ----  end----");
        }
        
        @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);
    }
  • 相关阅读:
    Product
    Testing
    mysql 获取当前日期及格式化
    Windows下重置Mysql密码
    如何在CLI命令行下运行PHP脚本,同时向PHP脚本传递参数?
    PHP和shell脚本遍历目录及其下子目录
    检测你的php代码执行效率
    NGINX 502 Bad Gateway
    linux文件类型详解
    查询软件和硬件列表清单[将文章里代码另存为 list.vbs,双击运行就会出现一个html页面]
  • 原文地址:https://www.cnblogs.com/zhaoyibing/p/9569655.html
Copyright © 2011-2022 走看看