线程
- 线程是轻量级子进程,是最小的处理单元
- 线程只能启动一次,第二次会
IllegalThreadStateException
start()
而不是run()
线程状态
import java.util.concurrent.TimeUnit;
public class ThreadStateDemo {
private int i = 10;
public static void main(String[] args) throws InterruptedException {
waitDemo();
final ThreadStateDemo stateDemo = new ThreadStateDemo();
final Thread thread = new ThreadState(stateDemo);
System.out.println("thread.getState() = " + thread.getState());
thread.start();
System.out.println("thread.getState() = " + thread.getState());
final Thread thread2 = new ThreadState(stateDemo);
thread2.start();
TimeUnit.SECONDS.sleep(2);
System.out.println("thread2.getState() = " + thread2.getState());
TimeUnit.SECONDS.sleep(200);
System.out.println("thread.getState() = " + thread.getState());
}
static void waitDemo() throws InterruptedException {
final ThreadStateDemo stateDemo = new ThreadStateDemo();
final Thread cut1 = new ThreadStateCut(stateDemo);
final Thread cut2 = new ThreadStateCut(stateDemo);
cut1.start();
cut2.start();
TimeUnit.SECONDS.sleep(11);
System.out.println("cut1 = " + cut1.getState());
System.out.println("cut2 = " + cut2.getState());
final Thread add = new ThreadStateAdd(stateDemo);
add.start();
TimeUnit.SECONDS.sleep(2);
System.out.println("cut1 = " + cut1.getState());
System.out.println("cut2 = " + cut2.getState());
TimeUnit.SECONDS.sleep(20);
System.exit(1086);
}
public synchronized void print() {
try {
TimeUnit.SECONDS.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " is run;");
}
public synchronized void intCut() {
try {
if (i >= 0) {
TimeUnit.SECONDS.sleep(1);
i--;
System.out.println(Thread.currentThread().getName() + i + "-- 了");
} else {
wait(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void intAdd() {
i += 10;
notifyAll();
}
}
class ThreadState extends Thread {
private final ThreadStateDemo print;
ThreadState(ThreadStateDemo print) {this.print = print;}
@Override
public void run() {
print.print();
}
}
class ThreadStateCut extends Thread {
private final ThreadStateDemo print;
ThreadStateCut(ThreadStateDemo print) {this.print = print;}
@Override
public void run() {
while (true) {
print.intCut();
}
}
}
class ThreadStateAdd extends Thread {
private final ThreadStateDemo print;
ThreadStateAdd(ThreadStateDemo print) {this.print = print;}
@Override
public void run() {
print.intAdd();
}
}
Runnable
Thread
Callable
- 实现
Callable
- 实现
call()
方法 - 有返回值
- 可以将异常抛出
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
public class MultiThread {
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println(Thread.currentThread().getName() + " is run;");
final Thread thread1 = new MyThread();
thread1.start();
final Thread thread2 = new Thread(new MyRunnable());
thread2.start();
final FutureTask<String> futureTask = new FutureTask<>(new MyCallable());
final Thread thread3 = new Thread(futureTask);
thread3.start();
System.out.println(futureTask.get());
}
}
class MyThread extends Thread {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " is run;");
}
}
class MyRunnable implements Runnable {
@Override
public void run() {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " is run;");
}
}
class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
TimeUnit.SECONDS.sleep(1);
return Thread.currentThread().getName() + " is run;";
}
}
线程池
ThreadPoolExecutor
- worker:工作线程,干活的
- workQueue:任务队列
- rejectedExecutionHandler:任务超出线程池负载时,如何处理
- corePoolSize :核心线程数
- maximumPoolSize:线程数量最大值
- keepAliveTime:空闲线程存活时间(空闲且超出
corePoolSize
部分) - ThreadFactory:自定义创建线程的工厂类
基本状态
- isShutdown 调用
shutdown
或者 shutdownNow
- isTerminaed 所有任务都已经关闭
提交任务基本流程
rejectedExecutionHandler 拒绝策略
- AbortPolicy策略:该策略会直接抛出异常,阻止系统正常工作
- CallerRunsPolicy策略:如果线程池的线程数量达到上限,该策略会把任务队列中的任务放在调用者线程当中运行
- DiscardOledestPolicy策略:该策略会丢弃任务队列中最老的一个任务,也就是当前任务队列中最先被添加进去的,马上要被执行的那个任务,并尝试再次提交
- DiscardPolicy策略:该策略会默默丢弃无法处理的任务,不予任何处理
ScheduledThreadPoolExecutor
- 继承了
ThreadPoolExecutor
schedule
scheduleAtFixedRate
等方法,延迟或者是定时执行任务- 比
Timer
更好
ForkJoinPool
- ForkJoinTask:执行的任务,可以拆分
fork()
和合并结果join()
- 有返回值
RecursiveTask
- 无返回值
RecursiveAction
- workQueue:变为双端队列,自身
LIFO
获取任务,其他worker 可以FIFO
窃取任务
Executors 中的线程池
类型 | 描述 |
---|
newCachedThreadPool | 可以自动扩容的线程池,可以重复利用空闲的线程 |
newFixedThreadPool | 固定数量线程池 |
newSingleThreadExecutor | 一个线程的线程池 |
newScheduledThreadPool | 定时执行任务的线程池,替代Timer |
newWorkStealingPool | 按CPU核心数创建的ForkJoinPool |
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.LongStream;
public class ThreadPoolDemo {
public static void main(String[] args) throws InterruptedException, ExecutionException {
final ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
final ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(3);
final ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
final ScheduledExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(3);
final ForkJoinPool newWorkStealingPool = (ForkJoinPool) Executors.newWorkStealingPool(3);
newScheduledThreadPool.scheduleAtFixedRate(new MyRunnable(), 1, 2, TimeUnit.SECONDS);
final ForkJoinTask<Long> forkJoinTask = newWorkStealingPool.submit(new MyRecursiveTask(0, 1000));
final long longReduce = LongStream.rangeClosed(0, 1000L).parallel().reduce(0, Long::sum);
System.out.println("longReduce = " + longReduce);
System.out.println("forkJoinTask = " + forkJoinTask.get());
for (int i = 0; i < 10; i++) {
newWorkStealingPool.execute(new MyRunnable());
newScheduledThreadPool.schedule(new MyRunnable(), 2, TimeUnit.SECONDS);
newCachedThreadPool.execute(new MyRunnable());
newFixedThreadPool.execute(new MyRunnable());
singleThreadExecutor.execute(new MyRunnable());
}
TimeUnit.SECONDS.sleep(5);
for (int i = 0; i < 10; i++) {
newCachedThreadPool.execute(new MyRunnable());
}
}
}
class MyRecursiveTask extends RecursiveTask<Long> {
private final int from;
private final int to;
public MyRecursiveTask(int from, int to) {
this.from = from;
this.to = to;
}
@Override
protected Long compute() {
if (to - from < 6) {
long total = 0;
for (int i = from; i <= to; i++) {
total += i;
}
return total;
} else {
int middle = (from + to) / 2;
MyRecursiveTask taskLeft = new MyRecursiveTask(from, middle);
MyRecursiveTask taskRight = new MyRecursiveTask(middle + 1, to);
taskLeft.fork();
taskRight.fork();
return taskLeft.join() + taskRight.join();
}
}
}
class MyRunnable implements Runnable {
@Override
public void run() {
try {
if (Thread.currentThread().getName().contains("2")) {
TimeUnit.SECONDS.sleep(1);
}
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " is run;");
}
}