JAVA中线程小谈

    xiaoxiao2022-07-14  166

    首先要介绍的是Object类的三个方法

    wait(long timeout) notify() notifyAll()

    这三个方法必须要在同步块中才能调用,即首先获取对象的monitor,常用的方式如下  

    synchronize(obj){        obj.wait()         ... }

    当对象调用wait方法的时候,就意味着放弃了该资源(monitor),并进入了等待队列。

    注:记得我们之前公司的产品,当一个线程需要睡眠的时候,就是用wait(long timeout)来实现的。我们的线程架构一般是   

     public void run(){          while(!shutdown){                  ...                do something          //需要sleep的时候        synchronize(obj){           obj.wait(time)         ... } } }

    这样就可以通过shutdown这个变量来控制该线程的关闭,同时,如果系统在关闭的时候,该线程处于sleep状态,我们只需要调用notify()方法就可以将该线程从睡眠状态叫醒,然后关闭。如果这里用sleep()方法的话,就需要用interupt()方法。

       

    protect boolean snooze(long sleeptime){ synchronized(obj){ if(wasAwoken){ wasAwoken=false; return true; } try{ if(sleeptime > 0){ obj.wait(sleeptime); if(wasAwoken){ wasAwoken=false; return true; } return false; }catch(InterruptedException ex){ log.info("Thread was interrupted-this should not happen,use wake() instead"); return true; } protect boolean wake(){ synchronized(obj){ wasAwoken=true; obj.notify(); } }

    这样就可以实现线程的睡眠和唤醒了。

     

    一般的大工程都会有很多deamon thread ,  具体什么是deamon thread可以去查询,但是如果一个application 没有用户进程的话,JVM会自动关闭该application, 一般deamon thread 都是一个一直在run的线程。

    1. 线程怎么样就关闭了??

       如果一个线程的run方法执行完毕,则这个线程就关闭了,所以一般的deamon thread 的run方法都是一个循环。

    像前面介绍的可以利用shutdown的变量来控制循环是否结束。从而使线程退出。

    2. 线程的run方法和start方法

       如果你直接调用一个线程的run方法,实际上还是在本线程执行了一个函数而已,并没有开启一个线程。只有当调用线程的start方法时候,才会在另一个线程中执行run方法。

    3. 线程池的概念

       ThreadPoolExecutor该类是线程池的主类,像常见的几种线程池都是通过工厂类来调用ThreadPoolExecutor() ,只是具体的参数不同。

    参考以下的链接:https://blog.csdn.net/xiaojin21cen/article/details/87359148

    public ThreadPoolExecutor(initcorePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler

       initcorePoolSize:是指在空闲的时候,线程池中保留的线程池数

      maximumPoolSize:是指线程池中最大的线程数

       keepAliveTime:线池空闲的时间,当大于这个时间,空闲的线程会被销毁,达到initcorePoolSize的数值

       TimeUnit:是指时间的单位

       BlockingQueue:是指当线程达到initcorePoolSize的时候,进来的任务都需要提交到队列中,就是该队列。

       另外两个参数具体不介绍了。

     线程池的处理流程。

       比如initcorePoolSize是10,maximumPoolSize是20,BlockingQueue是ArrayBlockingQueue(10-有界的队列)

         1.当一个任务提交到线程池的时候,如果当前线程池中的线程小于initcorePoolSize -10,则立即会创建新的线程来执行该任务。

         2.当一个任务提交到线程池的时候,当前线程池中的线程已经大于initcorePoolSize-10,则会将任务放到ArrayBlockingQueue中,等待空闲线程来执行。

      3. 当一个任务提交到线程池的时候,当前线程池的线程已经大于initcorePoolSize-10,且ArrayBlockingQueue也满了,但是线程池中的线程数小于maximumPoolSize-20,则会创建线程来执行任务。

    4.当一个任务提交到线程池的时候,线程数大于maximumPoolSize ,则会使用拒绝策略来处理。

     

    不同的线程池,主要是initcorePoolSize,maximumPoolSize,以及BlockingQueue的差别,具体可以参考

    https://www.jianshu.com/p/78424e42d4ea

     

    最新回复(0)