并发编程

并发编程(二):线程常用的方法

2020-04-03  本文已影响0人  codeMover

start和run

start方法

start方法

@Slf4j(topic = "ants.TestStart")
public class TestStart {
    public static void main(String[] args) {
        Thread t = new Thread("t1"){
            @Override
            public void run(){
                log.debug("执行run");
            }
        };
        t.start();
        log.debug("main 执行");
    }
}

sleep和yield

sleep

@Slf4j(topic = "ants.TestSleep")
public class TestSleep {
    public static void main(String[] args) {
         //测试线程sleep
        Thread t1 = new Thread("t1") {
            @SneakyThrows
            @Override
            public void run() {
                Thread.sleep(2000);
                log.debug("t1线程停留2秒后执行");
            }
        };
        t1.start();
        log.debug("t1线程状态:{}",t1.getState());
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.debug("t1线程状态:{}",t1.getState());
    }
}
@Slf4j(topic = "ants.TestSleepInterrupt")
public class TestSleepInterrupt {
    public static void main(String[] args) throws InterruptedException {
        //睡眠线程调用interrupt,会抛出(InterruptedException)异常
        Thread t1 = new Thread("t1") {
            @Override
            public void run() {
                //建议使用 TimeUnit.SECONDS.sleep,睡眠时间更直观
                log.debug("enter sleep ...");
                try {
                    TimeUnit.SECONDS.sleep(2);
                    log.debug("t1线程停留2秒后执行");
                } catch (InterruptedException e) {
                    log.debug("sleep interrupt ...");
                    e.printStackTrace();
                }
            }
        };
        t1.start();
        Thread.sleep(1000);
        log.debug(" t1 interrupt...");
        t1.interrupt();

    }
}

yield

@Slf4j(topic = "ants.TestYield")
public class TestYield {

    public static void main(String[] args)  {
        Test t1 = new Test("t1");
        Test t2 = new Test("t2");
        t1.start();
        t2.start();
    }
}
@Slf4j(topic = "ants.Test")
class Test extends Thread{
    public Test(String name){
        super(name);
    }

    @Override
    public void run() {
        for(int i = 1;i <=100; i++) {
            log.debug("t1线程执行第{}循环",i);
            if(i == 0)
                Thread.yield();
        }
    }
}

sleep与yield对比

线程优先级

@Slf4j(topic = "ants.TestPriority")
public class TestPriority {
    public static void main(String[] args) {
        Thread t1 = new Thread("t1") {
            @Override
            public void run() {
                int count=0;
                while(true){
                    log.debug("t1线程count值:{}",count++);
                }
            }
        };
        Thread t2 = new Thread("t2") {
            @Override
            public void run() {
                int count=0;
                while(true){
                    //yield(); //注释该行,发现打印结果count值接近,打开后t1线程获得CPU时间片多,count值大
                    log.debug("t2线程count值:{}",count++);
                }
            }
        };
        //t1.setPriority(Thread.MAX_PRIORITY);//单核CPU测试线程优先级效果明显
        //t2.setPriority(Thread.MIN_PRIORITY);
        t1.start();
        t2.start();

    }
}

防止CPU只用100%

  1. sleep线程睡眠,适合无锁场景
  2. wait或条件变量控制,都需要加锁,需要相关唤醒操作,一般用户同步场景

join

interrupt、isInterrupted、interrupt

@Slf4j(topic = "ants.TestInterrupt")
public class TestInterrupt {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread("t1") {
            //进入sleep wait 、join线程,异常标记为false
            @Override
            public void run() {
                log.debug("t1 interrupt");
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    log.debug("Thread.currentThread().interrupt() before:{}",Thread.currentThread().isInterrupted());
                    e.printStackTrace();
                    Thread.currentThread().interrupt();
                    log.debug("Thread.currentThread().interrupt():{}",Thread.currentThread().isInterrupted());
                }
            }
        };
        Thread t2 = new Thread("t2") {
            //正常执行的线程,打断标记为true
            @Override
            public void run() {
                log.debug("t2 interrupt");
                while(true){

                }

            }
        };
        Thread t3 = new Thread("t3") {
            //线程优雅关闭
            @Override
            public void run() {
                boolean flag = true;
                while(flag){
                    if(Thread.currentThread().isInterrupted()){
                        log.debug("t3 interrupt");
                        flag=false;
                    }
                }
                //处理退出循环后续逻辑
                log.debug("t3 退出循环");

            }
        };
        t1.start();
        Thread.sleep(1000);
        t1.interrupt();
        Thread.sleep(1000);
        log.debug("t1线程的打断标记:{}",t1.isInterrupted());
        log.debug("-------------------");
       t2.start();
        Thread.sleep(1000);
        t2.interrupt();
        Thread.sleep(1000);
        log.debug("t2线程的打断标记:{}",t2.isInterrupted());
        log.debug("-------------------");
        t3.start();
        Thread.sleep(1000);
        t3.interrupt();
        Thread.sleep(1000);

        log.debug("t3线程执行结束后打断标记:{}",t3.isInterrupted());
    }
}

park unpark

@Slf4j(topic = "ants.TestPark")
public class TestPark {
    public static void main(String[] args) {
        Thread t1 = new Thread("t1") {
            @Override
            public void run() {
                log.debug("t1 线程执行中-----");
                LockSupport.park();
                //log.debug("t1打断标记:{}",Thread.currentThread().isInterrupted());//不改变打断标记值
                log.debug("t1打断标记:{}",Thread.interrupted());//将打断标记置为false
                log.debug("t1 park  后面代码-----");
                LockSupport.park();
                log.debug("t1 再次 park  后面代码-----");

            }
        };
        t1.start();
        t1.interrupt();//打断正在执行的park线程
    }
}

上一篇 下一篇

猜你喜欢

热点阅读