线程
线程
线程的四种状态
- New:线程刚刚创建,还未加入线程调度
- Runnable:就绪态,调用 start() 后,线程加入线程调度。此时,只要获取到 CPU 时间片,就会进入运行态
- Running:运行态,线程获取到 CPU 时间片后,就会被 CPU 运行。可以通过 yield() 主动让出时间片,会使得线程返回就绪态
- Blocked:阻塞态,此时线程需要等待释放信号才能进入就绪态,如等待用户输入、等待锁被解除
- Dead:线程结束
线程中的变量
// 获取当前线程Thread thread = Thread.currentThread();
// 获取线程 IDlong id = thread.getId();
// 获取线程 Name String name = thread.getName();
// 获取线程优先级int priority = thread.getPriority();
publicfinalstaticint MIN_PRIORITY = 1;
publicfinalstaticint NORM_PRIORITY = 5;
publicfinalstaticint MAX_PRIORITY = 10;
// 判定线程是否为守护线程boolean isDaemon = thread.isDaemon();
// 判定线程是否被中断;被中断会进入阻塞 Blocked 状态boolean isInterrupted = thread.isInterrupted();
// 判定线程是否存活boolean isAlive = thread.isAlive();
创建线程的方式
- 继承Thread类
- 实现Runnable接口
- 实现Callable接口
- 使用线程池创建
1.submit和excute有什么区别
submit支持实现Runnable和Callable接口的线程不调用Future的get()方法会吃掉异常
excute只支持Runnable接口的现场
public class ThreadStudy {
public static void main(String[] args) throws ExecutionException, InterruptedException {
Thread1 tread1 = new Thread1();
tread1.setName("线程一");
tread1.start();
Thread thread2 = new Thread(new Thread2());
thread2.setName("线程二");
thread2.start();
FutureTask<String> task = new FutureTask<String>(new Thread3());
Thread thread3 = new Thread(task);
thread3.setName("线程三");
thread3.start();
ExecutorService executorService = Executors.newFixedThreadPool(2);
System.out.println("-----------------------");
executorService.execute(new Thread2());
executorService.execute(new Thread1());
executorService.submit(new Thread3());
Future<String> submit = executorService.submit(new Thread3());
String result = submit.get();
System.out.println(result);
Executors.newCachedThreadPool();
Executors.newSingleThreadExecutor();
executorService.shutdown();
}
}
class Thread1 extends Thread{
@Override
public void run() {
System.out.println("这是继承Thread创建的线程:"+Thread.currentThread().getName());
}
}
class Thread2 implements Runnable{
@Override
public void run() {
System.out.println("这是实现Runnable创建的线程:"+Thread.currentThread().getName());
}
}
class Thread3 implements Callable {
@Override
public String call() throws Exception {
System.out.println("这是实现Callable创建的线程:"+Thread.currentThread().getName());
return "这是实现Callable创建的线程:"+Thread.currentThread().getName();
}
}
线程池创建的线程
public ThreadPoolExecutor(int corePoolSize, // 核心线程池大小
int maximumPoolSize, // 最大线程池大小
long keepAliveTime, // 线程最大空闲时间
TimeUnit unit, // 时间单位
BlockingQueue<Runnable> workQueue, // 线程等待队列
ThreadFactory threadFactory, // 线程创建工程
RejectedExecutionHandler handler ) { //拒绝策列
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
-
newFixedThreadPool
-
参数分析:核心线程数和最大线程数相同,线程等待队列无限大
-
使用场景:Web服务器瞬间削峰,持续高峰情况需要注意队列阻塞
-
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
-
newCacheThreadPool
-
参数分析:核心线程池为0,最大线程数无限大,线程最大空闲时间60秒
-
使用场景:快速处理大量耗时较短的任务,如Netty的NIO接受请求时,可使用CachedThreadPool。
-
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
threadFactory);
}
-
newSchedulThreadPool
参数分析:传入核心线程
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue());
}
-
newSingeThreadExecutor
参数分析:依靠FinalizableDelegatedExecutorService执行操作
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
static class FinalizableDelegatedExecutorService
extends DelegatedExecutorService {
FinalizableDelegatedExecutorService(ExecutorService executor) {
super(executor);
}
protected void finalize() {
super.shutdown();
}
}
-
newSingThreadSchedulExecutor
参数:线程工厂
public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {
return new DelegatedScheduledExecutorService
(new ScheduledThreadPoolExecutor(1, threadFactory));
}
static class DelegatedScheduledExecutorService
extends DelegatedExecutorService
implements ScheduledExecutorService {
private final ScheduledExecutorService e;
DelegatedScheduledExecutorService(ScheduledExecutorService executor) {
super(executor);
e = executor;
}
public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
return e.schedule(command, delay, unit);
}
public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) {
return e.schedule(callable, delay, unit);
}
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {
return e.scheduleAtFixedRate(command, initialDelay, period, unit);
}
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) {
return e.scheduleWithFixedDelay(command, initialDelay, delay, unit);
}
}
自定义线程池
public class ThreadTest {
public static void main(String[] args) throws InterruptedException, IOException {
int corePoolSize = 2;
int maximumPoolSize = 4;
long keepAliveTime = 10;
TimeUnit unit = TimeUnit.SECONDS;
BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(2);
ThreadFactory threadFactory = new NameTreadFactory();
RejectedExecutionHandler handler = new MyIgnorePolicy();
ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit,
workQueue, threadFactory, handler);
executor.prestartAllCoreThreads(); // 预启动所有核心线程
for (int i = 1; i <= 10; i++) {
MyTask task = new MyTask(String.valueOf(i));
executor.execute(task);
}
System.in.read(); //阻塞主线程
}
static class NameTreadFactory implements ThreadFactory {
private final AtomicInteger mThreadNum = new AtomicInteger(1);
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r, "my-thread-" + mThreadNum.getAndIncrement());
System.out.println(t.getName() + " has been created");
return t;
}
}
public static class MyIgnorePolicy implements RejectedExecutionHandler {
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
doLog(r, e);
}
private void doLog(Runnable r, ThreadPoolExecutor e) {
// 可做日志记录等
System.err.println( r.toString() + " rejected");
// System.out.println("completedTaskCount: " + e.getCompletedTaskCount());
}
}
static class MyTask implements Runnable {
private String name;
public MyTask(String name) {
this.name = name;
}
@Override
public void run() {
try {
System.out.println(this.toString() + " is running!");
Thread.sleep(3000); //让任务执行慢点
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public String getName() {
return name;
}
@Override
public String toString() {
return "MyTask [name=" + name + "]";
}
}
}
线程池的大小
IO密集型
CPU密集型
Runtime.getRuntime().availableProcessors():获取CPU的核数
结论
总结,通过自定义线程池,我们可以更好的让线程池为我们所用,更加适应我的实际场景。