美文网首页
线程与线程池

线程与线程池

作者: 靈08_1024 | 来源:发表于2018-05-08 17:01 被阅读58次

    线程

    1、线程的状态。5个。

    2、实现线程的方法,及其区别。2种:Runnable、Thread(+2种:Callable、FutureTask)。

    3、start()和run()的区别。

    4、Thread.sleep()和Thread.yield()区别
    yield,音标 /jild/。线程的礼让,该线程退回到就绪状态(然后所有的就绪的线程凭借优先级抢资源)。
    sleep,线程的阻塞(当阻塞时间结束,线程转入就绪状态)。

    5、wait和sleep的区别
    1)wait是object的方法,sleep是thread的静态方法;
    2)wait需要在synchronized范围内使用,否则抛错Exception in thread "main" java.lang.IllegalMonitorStateException,而sleep则不需要;
    3)wait是对象监听器的线程的等待,当该对象wait时,当前线程进入等待,其notify方法是随机唤起一个(等待该对象监听器的)线程;sleep是当前线程的沉睡,该线程的对象锁还是持有的;
    4)wait出让系统资源,进入线程池中等待;sleep不会出让锁。二者都会让出CPU。

    5、用户线程(user Thread)和守护线程(daemon Thread)的区别。
    1)守护线程的区别在于thread.setDaemon(true),设置了就是守护线程,且必须在start()之前设置。
    2)守护线程依赖于用户线程,没有用户线程,守护线程不存在。即当用户线程运行完毕,此时不管守护线程是否运行或运行完毕,立即停止。

    6、线程调用的两种方式:
    1)直接使用start()方法(在主方法中显式迭代调用或者构造方法中,便于外部隐式调用);
    2)使用Executor来调用(CachedThreadPool()或者FixedThreadPool())。
    两种方法的区别是:Executor执行线程都是隐式的。而且在构造方法中调用start()方法对于多线程是不安全的,而Executor则不会。

     @Test
        public void testCachePool(){
            ExecutorService exec = Executors.newCachedThreadPool();
            for (int i = 0; i < 5; i++) {
                exec.execute(new LiftOff());
            }
            exec.shutdown();
        }
    

    7、停止一个运行中线程的方法:
    1)interrupt方法;
    2)使用退出标志;
    3)stop,但不建议(J8废除,原因是可能导致数据不一致)。

    关于stop方法,参考https://blog.csdn.net/a158123/article/details/78776145


    线程池

    6、Executor调用线程的两种方式的区别:
    newCachedThreadPool()会为每一个任务都分配线程;
    newFixedThreadPool(long)会限定可使用的线程数量,在前面的任务执行完之后,会将空线程分配给其他的任务。

    7、在并发时,一个任务不能依赖于另一个任务,因为任务的关闭顺序无法保证。解决:1.依赖于非任务对象(volatile变量)来解决。2.锁。

    8、锁的方式:2种,synchronize和Lock。区别在于Lock更加细粒度,比如锁的尝试获取,锁的锁定时间。

    9、线程池的状态:5个。
    1.running
    2.shutdown
    3.stop
    4.tidying(当workQueue为0时,进入该状态)
    5.terminated

    10、shutdown和stop的区别。
    二者都有线程池停止之意,且都不接收新线程了。但shutdown会处理掉已接收和正在执行的线程,而stop会中断所有的已接收和正在执行的线程。

    11、threadPoolExecutor的参数含义。
    corePoolSize:核心线程数。即最小存活线程数。
    maximunPoolSize:最大线程数。
    keepAliveTime:线程长连接时间。
    unit:长连接单位。
    workQueue:工作队列。当线程达到核心数时,多余的线程会放在此处,线程的创建与消亡,都会经过这里。
    threadFactory:线程创建工厂(有一个默认工厂)。
    handler:拒绝策略。当多余的线程请求时,执行的策略。默认是拒绝策略。
    ps:关于workQueue:当需要使用一个线程时,会先看核心线程有无空闲线程,若有,则直接使用,没有,则创建并放在队列中等待被使用;当线程用完时,也会放在队列中,等待一会,实在没人用且已达到核心数时,会消亡该线程。

    12、线程的循环调用(如每隔5秒调用线程):
    这是一个初始化后延迟1秒,每隔5秒执行任务(秒单位共享)。

    ScheduledExecutorService service = Executors.newScheduledThreadPool(5);
            service.scheduleAtFixedRate(new Runnable() {
                @Override
                public void run() {
                    log.info("ww");
                }
            }, 1, 5, TimeUnit.SECONDS);
    

    这是一个初始化后延迟1毫秒,每隔5秒执行任务。默认单位为毫秒。

    new Timer().scheduleAtFixedRate(new TimerTask() {
                @Override
                public void run() {
                    log.info("tt");
                }
            },1,5*1000);
    

    参考:Java多线程线程池(4)--线程池的五种状态

    相关文章

      网友评论

          本文标题:线程与线程池

          本文链接:https://www.haomeiwen.com/subject/nocztftx.html