java多线程1(Thread,Runnable,ThreadPoolExecutor)

1:PV操作

PV操作由P操作和V操作组成,对信号量的操作,具体定义:
P(S):
1. 将信号量S的值减1,S=S-1
2. 如果S 0,则该进程继续执行;否则进入等待状态,排入等待队列
V(S):
1.将i信号量S的值加1,S=S+1
2.如果S > 0,则该进程继续执行;否则释放队列中第一个等待信号量的进程。

2:java多线程

2.1 Thread和Runnable

java实现线程有两种方式,一种是自定义一个集成自Thread的类,重写run函数;还有一种是直接实现Runnable接口。
其实本质上这两种方式都是提供一个run函数给线程调用。我们看一下Thread的源码。

public Thread(Runnable target) {
    //此处可以看出是将我们传入的runnable对象赋给Thread的target对象
    init(null, target, "Thread-" + nextThreadNum(), 0);
}
//此处的run函数提供给线程调用
public void run() {
    //这里判断有没有target对象,如果有说明我们传入调用了Thread(Runnable)构造函数,此处实际即调用了我们重写的Runnable接口的run函数。
    if (target != null) {
        target.run();
    }
}
//如果我们自定义的类继承了Thread类,并且重写了run函数,那么我们实际给线程调用的函数即是我们重写的run函数。

2.2 线程池相关类

ThreadPoolExecutor的具体介绍可以看这篇博客
http://www.cnblogs.com/dolphin0520/p/3932921.html

ThreadPoolExecutor

我们先看两张图

  • 任务执行流程图
    这里写图片描述
  • 任务队列图
    这里写图片描述
    几个关键点
  • corePoolSize 核心线程池大小,线程池刚启动时来一个任务就会创建一个线程去执行这个任务,直到达到corePoolSize个线程,这时再来的任务就会加到任务队列中去,直到任务队列满了,这时会尝试创建新的线程,但是总线程数量必须少于maximumPoolSize,如果线程也不能创建了,这时就会拒绝执行任务了。
  • maximumPoolSize 最大线程数,线程池总线程数量不得多于maximumPoolSize
  • keepAliveTime 线程存货时间,主要是在最大线程数到核心线程数之间的线程存活时间,比如corePoolSize = 10,maximumPoolSize =100。当线程池达到100时,这时每个线程不执行且过了keepAliveTime 的时间后就会消失,但是当线程池数量到达corePoolSize 线程不在消失。也就是说keepAliveTime 不起作用了。
  • Queue任务队列 有三种类型(无限队列、直接队列、有限队列)
    直接队列来一个任务会直接尝试创建新线程执行。
    无限队列会当线程池数量达到corePoolSize 时新来的任务都会加入队列中,这时maximumPoolSize 就不起作用了。
    有限队列在线程达到corePoolSize 且任务队列已满时来一个任务会尝试继续创建线程,知道达到maximumPoolSize

Executors是创建线程池的工厂类。提供了以下几个主要方法

  • newCachedThreadPool函数
public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

可以看出创建了一个核心线程数为0,最大线程数为一个Integer能表示的最大值,存活时间为60秒。队列为SynchronousQueue直接队列。这种情况下每来一个任务就创建一个线程执行。直到创建的线程数大于Integer.MAX_VALUE当然一般情况下不会出现。每一个线程的存货时间是60秒超过60秒后自动销毁。

  • newFixedThreadPool函数
public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}

可以看出创建了一个核心线程数为传入的nThreads,最大线程数也为nThreads,存活时间为0秒。队列为LinkedBlockingQueue即不保存队列任务。这种情况下每来一个任务首先看线程池数量有没有到nThreads,如果没有达到则创建一个新的线程并执行,否则加入队列中,等待执行。此处LinkedBlockingQueue没有指定大小即最多可以接收Integer.MAX_VALUE个缓冲任务。相当于创建了nThreads个线程来执行队列中的任务。

  • newSingleThreadExecutor
public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}

和上面的newFixedThreadPool类似,只不过这里只有一个线程,即使用一个线程执行任务队列中的任务。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值