1、继承Thread类
2、实现Runnable接口
3、实现Callable接口
这种方式需要结合FutureTask类使用
public static void main(String[] args) throws ExecutionException, InterruptedException {
Callable callable = new Callable() {
@Override
public Object call() throws Exception {
return null;
}
};
FutureTask<Integer> future1 = new FutureTask(() -> {
int sum = 0;
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+"---"+i);
sum += i;
}
return sum;
});
new Thread(future1).start();
FutureTask<Integer> future2 = new FutureTask(() -> {
int sum = 0;
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()+"---"+i);
sum += i;
}
return sum;
});
new Thread(future2).start();
System.out.println(future1.get());
System.out.println(future2.get());
}
// 运行结果:
Thread-0---0
Thread-0---1
Thread-0---2
Thread-1---0
Thread-0---3
Thread-1---1
Thread-0---4
Thread-1---2
Thread-0---5
Thread-1---3
Thread-1---4
Thread-0---6
Thread-0---7
Thread-0---8
Thread-0---9
45
10
注意:只有线程执行结束后才会执行get(),所以FutureTask也用于闭锁。
闭锁(Latch):一种同步方法,可以延迟线程的进度直到线程到达某个终点状态。通俗的讲就是,一个闭锁相当于一扇大门,在大门打开之前所有线程都被阻断,一旦大门打开所有线程都将通过,但是一旦大门打开,所有线程都通过了,那么这个闭锁的状态就失效了,门的状态也就不能变了,只能是打开状态。也就是说闭锁的状态是一次性的,它确保在闭锁打开之前所有特定的活动都需要在闭锁打开之后才能完成。
4、线程池
提供了一个线程队列,队列中保存着所有等待状态的线程。避免了创建与销毁额外开销,提高了响应的速度
引用:
线程池的体系结构:
java.util.concurrent.Executor : 负责线程的使用与调度的根接口
|--*ExecutorService 子接口: 线程池的主要接口
|--ThreadPoolExecutor 线程池的实现类
|--ScheduledExecutorService 子接口:负责线程的调度
|--ScheduledThreadPoolExecutor :继承 ThreadPoolExecutor, 实现 ScheduledExecutorService
工具类 : Executors
a) ExecutorService newFixedThreadPool() : 创建固定大小的线程池
b) ExecutorService newCachedThreadPool() : 缓存线程池,线程池的数量不固定,可以根据需求自动的更改数量。
c) ExecutorService newSingleThreadExecutor() : 创建单个线程池。线程池中只有一个线程
d) ScheduledExecutorService newScheduledThreadPool() : 创建固定大小的线程,`与ExecutorService 的区别是还可以延迟或定时的执行任务。
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(5);
Future<Integer> submit1 = executorService.submit(() -> {
int sum = 0;
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "---" + i);
sum += i;
}
return sum;
});
Future<Integer> submit2 = executorService.submit(() -> {
int sum = 0;
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + "---" + i);
sum += i;
}
return sum;
});
System.out.println(submit1.get());
System.out.println(submit2.get());
}