线程池

java.uitl.concurrent.ThreadPoolExecutor类是线程池中最核心的一个类

1.corePoolSize: 核心池的大小,默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去
                执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中;

2.maximumPoolSize : 线程池最大线程数,它表示在线程池中最多能创建多少个线程;


3.keepAliveTime : 表示线程没有任务执行时最多保持多久时间会终止.默认情况下,只有当线程池中的线程数大于
                corePoolSize时,keepAliveTime才会起作用,直到线程池中的线程数不大于corePoolSize时,如果一个线程
                空闲的时间达到keepAliveTime,则会终止,直到线程池中的线程数不超过corePoolSize。但是如果调用了
                allowCoreThreadTimeOut(boolean)方法,在线程池中的线程数不大于corePoolSize时,keepAliveTime
                参数也会起作用,直到线程池中的线程数为0;
                
4.unit          :  参数keepAliveTime的时间单位,有7种取值,在TimeUnit类中有7种静态属性:
                 TimeUnit.DAYS;               //天
                 TimeUnit.HOURS;             //小时
                 TimeUnit.MINUTES;           //分钟
                 TimeUnit.SECONDS;           //秒    
                 TimeUnit.MILLISECONDS;      //毫秒
                 TimeUnit.MICROSECONDS;      //微妙
                 TimeUnit.NANOSECONDS;       //纳秒
5.workQueue      : 一个阻塞队列,用来存储等待执行的任务
                 ArrayBlockingQueue;
                 LinkedBlockingQueue;
                 SynchronousQueue;
                          ArrayBlockingQueue和PriorityBlockingQueue使用较少,
                        一般使用LinkedBlockingQueue和Synchronous。线程池的排队策略与BlockingQueue有关。

6.threadFactory  : 线程工厂,主要用来创建线程;

7.handler        : 表示当拒绝处理任务时的策略,
                ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。 
                ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。 
                ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
                ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务 
    
在ThreadPoolExecutor类中有几个非常重要的方法:
    

    execute() : 方法实际上是Executor中声明的方法,在ThreadPoolExecutor进行了具体的实现,
                这个方法是ThreadPoolExecutor的核心方法,通过这个方法可以向线程池提交一个任务,
                交由线程池去执行。
    submit()  : 方法是在ExecutorService中声明的方法,在AbstractExecutorService就已经有了具体的实现,
                在ThreadPoolExecutor中并没有对其进行重写,这个方法也是用来向线程池提交任务的,
                但是它和execute()方法不同,它能够返回任务执行的结果,去看submit()方法的实现,
                会发现它实际上还是调用的execute()方法,只不过它利用了Future来获取任务执行结果
                
    shutdown()和shutdownNow()是用来关闭线程池的。
    


二.深入剖析线程池实现原理

1.线程池状态
             runState表示当前线程池的状态,它是一个volatile变量用来保证线程之间的可见性;
             当创建线程池后,初始时,线程池处于RUNNING状态;

  如果调用了shutdown()方法,则线程池处于SHUTDOWN状态,此时线程池不能够接受新的任务,它会等待所有任务执行完毕;

  如果调用了shutdownNow()方法,则线程池处于STOP状态,此时线程池不能接受新的任务,并且会去尝试终止正在执行的任务;

  当线程池处于SHUTDOWN或STOP状态,并且所有工作线程已经销毁,任务缓存队列已经清空或执行结束后,线程池被设置为TERMINATED状态

以上内容:
   https://www.cnblogs.com/dolphin0520/p/3932921.html


Java并发编程:Callable、Future和FutureTask


 Callable接口可以看作是Runnable接口的补充,call方法带有返回值,并且可以抛出异常。
把Callable实例当作参数,生成一个FutureTask的对象,然后把这个对象当作一个Runnable,作为参数另起线程。

Future的核心思想是:一个方法f,计算过程可能非常耗时,等待f返回,显然不明智。可以在调用f的时候,立马返回一个Future,可以通过Future这个数据结构去控制方法f的计算过程。

这里的控制包括:

get方法:获取计算结果(如果还没计算完,也是必须等待的)

cancel方法:还没计算完,可以取消计算过程

isDone方法:判断是否计算完

isCancelled方法:判断计算是否被取消


https://www.cnblogs.com/dolphin0520/p/3949310.html


1.1.1、实现原理


方式1:自定义类继承Thread类,重写run方法,调用start启动线程,会自动调用我们线程类中的run方法。
方式2:自定义类,实现Runnable接口,把任务对象传给Thread对象。调用Thread对象的start方法,执行Thread的run


总结多线程的安全问题发生的原因:
1、    首先必须有多线程。
2、    多个线程在操作共享的数据,并且对共享数据有修改。 
3、    本质原因是CPU在处理多个线程的时候,在操作共享数据的多条代码之间进行切换导致的。


Java线程池

Java通过Executors提供四种线程池,分别为:
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。


 1.使用Callable+Future获取执行结果


public class Test {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newCachedThreadPool();
        Task task = new Task();
        Future<Integer> result = executor.submit(task);
        executor.shutdown();
         
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
         
        System.out.println("主线程在执行任务");
         
        try {
            System.out.println("task运行结果"+result.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
         
        System.out.println("所有任务执行完毕");
    }
}
class Task implements Callable<Integer>{
    @Override
    public Integer call() throws Exception {
        System.out.println("子线程在进行计算");
        Thread.sleep(3000);
        int sum = 0;
        for(int i=0;i<100;i++)
            sum += i;
        return sum;
    }
}

2.使用Callable+FutureTask获取执行结果


public class Test {
    public static void main(String[] args) {
        //第一种方式
        ExecutorService executor = Executors.newCachedThreadPool();
        Task task = new Task();
        FutureTask<Integer> futureTask = new FutureTask<Integer>(task);
        executor.submit(futureTask);
        executor.shutdown();
         
        //第二种方式,注意这种方式和第一种方式效果是类似的,只不过一个使用的是ExecutorService,一个使用的是Thread
        /*Task task = new Task();
        FutureTask<Integer> futureTask = new FutureTask<Integer>(task);
        Thread thread = new Thread(futureTask);
        thread.start();*/
         
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
         
        System.out.println("主线程在执行任务");
         
        try {
            System.out.println("task运行结果"+futureTask.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
         
        System.out.println("所有任务执行完毕");
    }
}
class Task implements Callable<Integer>{
    @Override
    public Integer call() throws Exception {
        System.out.println("子线程在进行计算");
        Thread.sleep(3000);
        int sum = 0;
        for(int i=0;i<100;i++)
            sum += i;
        return sum;
    }
}


https://blog.youkuaiyun.com/doutao6677/article/details/55509719

                        

转载于:https://my.oschina.net/u/3892666/blog/2251222

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值