一、简介
多线程创建方式有三种,一种是继成Thread类;一种是实现Runnable接口;一种是使用Callable接口和Future接口组合,它和runnable接口方式的区别是前者的run方法返回VOID,后者可以返回线程中存储的值;一般采用线程池来创建线程,这个在后续写线程池的时候再写。
二、创建方式
2.1 继承Thread类
2.1.0 思路
- 继承Thread类,覆盖run方法;
2.1.1 案例
/**
* @author qjwyss
* @date 2019/3/29
* @description
*/
public class ThreadStyleThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + "输出的i值:" + i);
}
}
}
/**
* @author qjwyss
* @date 2019/3/29
* @description
*/
public class ThreadTest {
public static void main(String[] args) {
Thread thread1 = new ThreadStyleThread();
Thread thread2 = new ThreadStyleThread();
thread1.start();
thread2.start();
}
}
2.2 实现Runnable接口
2.2.0 思路
- 实现Runnable接口,覆盖run方法,然后作为Thread的类的参数进行构造;
2.2.1 案例
/**
* @author qjwyss
* @date 2019/3/29
* @description
*/
public class ThreadTest {
public static void main(String[] args) {
// 匿名内部类写法
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("线程" + Thread.currentThread().getName() + "输出的" + i);
}
}
});
// lambda写法
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 100; i++) {
System.out.println("线程" + Thread.currentThread().getName() + "输出的" + i);
}
});
thread1.start();
thread2.start();
}
}
2.3 使用Callable接口和Future接口组合
2.3.0 思路
- 实现Callable接口,并作为FutureTask的构造参数构造FutureTask, 然后将FutureTask作为Thread的构造参数构造Thread.
2.3.1 案例
/**
* @author qjwyss
* @date 2019/3/29
* @description
*/
public class ThreadTest {
public static void main(String[] args) {
// 需要返回值的方式
FutureTask<Integer> futureTask = new FutureTask<>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
Integer sum = 0;
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + "的I值:" + i);
sum += i;
}
return sum;
}
});
Thread thread1 = new Thread(futureTask);
// 简写方式
Thread thread2 = new Thread(new FutureTask<Integer>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
Integer sum = 0;
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + "的I值:" + i);
sum += i;
}
return sum;
}
}));
// lambda写法
Thread thread3 = new Thread(new FutureTask(() -> {
Integer sum = 0;
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + "的I值:" + i);
sum += i;
}
return sum;
}));
thread1.start();
thread2.start();
thread3.start();
// 使用futuerTask获取线程中存储的值
try {
Integer sum = futureTask.get();
System.out.println("线程中计算的结果为:" + sum);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
三、多线程系列链接
- 多线程系列(一)------ 线程的状态及转换
- 多线程系列(二)------ 线程的创建方式
- 多线程系列(三)------ 线程常用方法
- 多线程系列(四)------ 线程优先级和守护线程和终止线程的方式
-
多线程系列(六)------ 生产者消费者案例
- 多线程系列(七)------ synchronized关键字简单使用以及可重入性
- 多线程系列(八)------ synchronized关键字原理以及锁优化
- volatile相关
- ThreadLocal相关
- 锁LOCK相关系列
- 原子类相关系列
- 并发集合相关系列
- 线程池相关系列