java高并发-Thread api介绍

1.sleep

public static void sleep(long millis) throws InterruptedException    //millis:毫秒数

public static void sleep(long millis, int nanos) throws InterruptedException    //millis:毫秒数, nanos:纳秒数

会使当前线程进入指定毫秒数休眠,暂停执行,并且不会放弃monitor锁的所有权

Thread.sleep()只会导致当前线程进入睡眠

 

2.TimeUnit

Thread.sleep(12257088L) == TimeUnit.HOURS.sleep(3); TimeUnit.MINUTES.sleep(24); TimeUnit.SECOND.sleep(17); TimeUnit.MILLISECONDS.sleep(88);

是休眠的util类,更加方便

 

3.yield

是一种启发式方法,提醒调度器我愿意放弃当前的cpu资源,如果cpu资源不紧张,则会忽略这种提醒

调用yield方法会使当前线程从running状态到runnable状态

 

4.yield和sleep的区别

(1)sleep会导致当前线程暂停指定的时间,没有cpu时间片的消耗

(2)yield只是对cpu调度器的一个提示,如果cpu调度器没有忽略这个提示,它会导致线程上下问的切换

(3)sleep会使线程短暂block,会在给定的时间内释放cpu资源

(4)yield会使running状态的thread进入runnable状态(如果cpu调度器没有忽略这个提示的话)

(5)sleep几乎百分百地完成了给定时间的休眠,而yield的提示并不能一定担保

(6)一个线程sleep另一个线程调用interrupt会捕获到中断信号,而yield则不会

 

5.设置线程的优先级

public final void setPriority(int newPriority) 设置线程的优先级

public find int gettPriority() 获取线程的优先级

newPriority 介于[1, 10]之间,如果指定的线程优先级大于线程所在的group优先级,那么指定的优先级将会失效,取而代之的是group的最大优先级,默认优先级和它父类保持一致,一般是5,因为main线程的优先级就是5

如果cpu比较闲,设置优先级几乎没作用,所以不要依赖于设置优先级

 

6.获取线程id

public long getId() 获取线程唯一的id,在整个jvm中id是唯一的

 

7.获取当前线程

public static Thread currentThread() 用于返回当前线程的索引,

 

8.设置线程上下文类加载器

public ClassLoader getContextClassLoad() 获取线程上下文的类加载器,就是当前线程是由哪个类加载器加载的,如果没有指定,那么保持和父线程同样的类加载器

public void setClassLoader(ClassLoad cl) 设置该线程的类加载器,可以打破java类加载器的父委托机制,也被成为java类加载器的后门

 

9.线程中断(interrupt)

public void interrupt()

public static boolean interrupted()

public boolean isInterrupted()

interrupt会打断线程执行wait(...),sleep(...),join(...),io操作,wakeup方法造成的阻塞

如果线程在阻塞状态被打断,那么会抛出一个Interrupted Exception 的异常,如果线程死亡,那么执行interrupt将会无效

public class ThreadInterrupt {

    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            try {
                TimeUnit.MINUTES.sleep(1);
            } catch (InterruptedException e) {
                System.out.println("oh, i am be interrupted");
            }
        });
        thread.start();
        try {
            TimeUnit.MILLISECONDS.sleep(2);
            thread.interrupt();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

thread.isInterrupted()会判断线程是否中断,并且擦除interrupt标识,也就是说第一次调用thread.isInterrupted()方法,会返回true,但是第二次调用时,就会永远返回false

 

10.线程join

属于一个中断方法

public final void join() throws InterruptedException

public final synchronized void join(long millis, int nanos) throws InterruptedException

public final synchronized void join(long millis) throws InterruptedException

join某个线程a, 会使当前线程b进入等待,等待线程a结束生命周期,或者到达给定的时间,那么当时b线程进入blocked状态

public interface FightQuery {

    List<String> get();
}
public class FightQueryTask extends Thread implements FightQuery {

    private final String origin;

    private final String destination;

    private final List<String> flightList = new ArrayList<>();

    public FightQueryTask(String airline, String origin, String destination) {
        super("[" + airline + "]");
        this.origin = origin;
        this.destination = destination;
    }

    @Override
    public void run() {
        System.out.println("query from:" + getName() + " " + origin + " " + destination);
        int randomVal = ThreadLocalRandom.current().nextInt(10);
        try {
            TimeUnit.SECONDS.sleep(randomVal);
            this.flightList.add(getName() + "-" + randomVal);
            System.out.printf("the fight:%s list query successful\n", getName());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public List<String> get() {
        return this.flightList;
    }
}
public class FightQueryExample {

    //合作的各大航空公司
    private static List<String> fightCompany = Arrays.asList(
            "csa", "cea", "hna"
    );

    public static void main(String[] args) {
        List<String> results = search("sh", "bj");
        System.out.println("==========result============");
        results.forEach(System.out::println);
    }

    private static List<String> search(String orignal, String dest) {
        final List<String> result = new ArrayList<>();
        //创建查询航班信息的线程列表
        List<FightQueryTask> tasks = fightCompany.stream().map(f -> createSearchTask(f, orignal, dest)).collect(Collectors.toList());
        //分别启动这些线程
        tasks.forEach(Thread::start);
        //分别调用每一个线程的join方法,阻塞当前线程
        tasks.forEach(t -> {
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        //在此之前,当前线程会阻塞住,获取每一个查询线程的结果,并且加入到result中
        tasks.stream().map(FightQueryTask::get).forEach(result::addAll);
        return result;
    }

    private static FightQueryTask createSearchTask(String fight, String orignal, String dest) {
        return new FightQueryTask(fight, orignal, dest);
    }
}

有点难,反正我是不会。。。。

 

11.关闭线程

(1)正常关闭

线程结束生命周期正常关闭

捕捉中断信号关闭线程

public class InterruptThreadExit {

    public static void main(String[] args) {
        Thread t = new Thread() {
            @Override
            public void run() {
                System.out.println("i will start work");
                while (!isInterrupted()) {
                    //working
                }
                System.out.println("i will be finishing");
            }
        };
        t.start();
        try {
            TimeUnit.MILLISECONDS.sleep(1);
            System.out.println("system will be shutdown");
            t.interrupt();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

使用volatile开关控制

public class FlagThreadExit {

    static class MyTask extends Thread {

        private volatile boolean closed = false;

        @Override
        public void run() {
            System.out.println("i will start work");
            while (!closed && !isInterrupted()) {
                //正在运行
            }
            System.out.println("i will be existing");
        }

        public void close() {
            this.closed = true;
            this.isInterrupted();
        }
    }

    public static void main(String[] args) {
        MyTask myTask = new MyTask();
        myTask.start();
        try {
            TimeUnit.MILLISECONDS.sleep(1);
            System.out.println("system will be shutdown");
            myTask.close();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

  

(2)非正常关闭

异常退出

在线程执行过程中,是不允许抛出checked异常的

进程假死

 

posted @ 2020-06-04 17:16  豆莱浆渠  阅读(302)  评论(0编辑  收藏  举报