zoukankan      html  css  js  c++  java
  • 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
    ", 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异常的

    进程假死

  • 相关阅读:
    jython运行python文件
    jython查看帮助help和模块modules
    ubuntu 星际译王3.0.1-9.4隐藏主界面不能打开
    ubuntu火狐(firfox)浏览器安装视频插件
    ubuntu安装mp4播放器vlc & smplayer
    ubuntu+Windows双系统默认引导顺序
    notepad++ 各种颜色调整
    Linux绿色版软件expect
    aix下shell读取脚本文件并逐行执行
    AIX系统常用命令
  • 原文地址:https://www.cnblogs.com/freeht/p/13044779.html
Copyright © 2011-2022 走看看