线程:有时被称为轻量级进程 (Lightweight Process,LWP),是程序执行流的最小单元。
多线程:(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。
线程池:是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。
package com.carl.threaddemo;
public class ThreadIm1 {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ThreadIm1");
}
}).start();
System.out.println("end");
}
}
package com.carl.threaddemo;
public class ThreadIm2 implements Runnable {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ThreadIm2");
}
public static void main(String[] args) {
Thread t = new Thread(new ThreadIm2());
t.start();;
System.out.println("end");
}
}
由于线程是系统中的资源,频繁创建和销毁将带来性能上的开销,所以引入了线程池,
一来避免线程间抢占系统资源导致的阻塞,
二来提高了线程的利用率,
三来可对线程进行管理并提供定时执行等功能
1)newCachedThreadPool 是一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。对于执行很多短期异步任务的程序而言,这些线程池通常可提高程序性能。调用 execute() 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。因此,长时间保持空闲的线程池不会使用任何资源。注意,可以使用 ThreadPoolExecutor 构造方法创建具有类似属性但细节不同(例如超时参数)的线程池。
2)newSingleThreadExecutor 创建是一个单线程池,也就是该线程池只有一个线程在工作,所有的任务是串行执行的,如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它,此线程池保证所有任务的执行顺序按照任务的提交顺序执行。
3)newFixedThreadPool 创建固定大小的线程池,每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小,线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。
4)newScheduledThreadPool 创建一个大小无限的线程池,此线程池支持定时以及周期性执行任务的需求。
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, defaultHandler);
}
1)corePoolSize:线程池的核心线程数,一般情况下不管有没有任务都会一直在线程池中一直存活,只有在 ThreadPoolExecutor 中的方法 allowCoreThreadTimeOut(boolean value) 设置为 true 时,闲置的核心线程会存在超时机制,如果在指定时间没有新任务来时,核心线程也会被终止,而这个时间间隔由第 3 个属性 keepAliveTime 指定。
2)maximumPoolSize:线程池所能容纳的最大线程数,当活动的线程数达到这个值后,后续的新任务将会被阻塞。
3)keepAliveTime:控制线程闲置时的超时时长,超过则终止该线程。一般情况下用于非核心线程,只有在 ThreadPoolExecutor 中的方法 allowCoreThreadTimeOut(boolean value) 设置为 true 时,也作用于核心线程。
4)unit:用于指定 keepAliveTime 参数的时间单位,TimeUnit 是个 enum 枚举类型,常用的有:TimeUnit.HOURS(小时)、TimeUnit.MINUTES(分钟)、TimeUnit.SECONDS(秒) 和 TimeUnit.MILLISECONDS(毫秒) 等。
5)workQueue:线程池的任务队列,通过线程池的 execute(Runnable command) 方法会将任务 Runnable 存储在队列中。
6)threadFactory:线程工厂,它是一个接口,用来为线程池创建新线程的。
ThreadPoolExecutor 提供了两个方法,用于线程池的关闭,分别是 shutdown() 和 shutdownNow()。
shutdown():不会立即的终止线程池,而是要等所有任务缓存队列中的任务都执行完后才终止,但再也不会接受新的任务。
shutdownNow():立即终止线程池,并尝试打断正在执行的任务,并且清空任务缓存队列,返回尚未执行的任务。
package com.carl.threaddemo;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class CallableThreadPoolDemo {
public static ExecutorService single = Executors.newSingleThreadExecutor();
public static void main(String[] args) throws InterruptedException {
Callable<String> callable = new Callable<String>(){
@Override
public String call() throws Exception {
Thread.sleep(1000);
System.out.println("calling");
return "haha";
}
};
single.submit(callable);
// Future<String> f = single.submit(callable);
// try {
//获取callable返回值
// System.out.println(f.get());
// } catch (ExecutionException e) {
// e.printStackTrace();
// }
System.out.println("end");
}
}
package com.carl.threaddemo;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class CallableFutureTask {
public static void main(String[] args) throws InterruptedException, TimeoutException {
Callable<String> callable = new Callable<String>(){
@Override
public String call() throws Exception {
System.out.println(System.currentTimeMillis() + " calling");
return "haha";
}
};
FutureTask<String> fta = new FutureTask<String>(callable);
new Thread(fta).start();
System.out.println(System.currentTimeMillis() + " end");
System.out.println();
FutureTask<String> fts = new FutureTask<String>(callable);
try {
fts.run();
fts.get();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println(System.currentTimeMillis() + " end");
}
}
《java 并发编程实战》