多线程学习(一):线程创建的方式
使用多线程时,不同方式最终都通过调用
Thread
类的start
方法启动线程
1. 继承Thread类
- 继承Thread类
- 重写run()方法
- 需要执行的代码写在方法体中
- 调用start()方法
public class ThreadCreate1 extends Thread{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + ": <子线程>-启动");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(Thread.currentThread().getName() + ": <子线程>-结束");
}
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName() + ": <主线程>-启动");
new ThreadCreate1().start();
new ThreadCreate1().start();
new ThreadCreate1().start();
System.out.println(Thread.currentThread().getName() + ": <主线程>-结束");
}
}
2. 实现Runnable接口
- 实现Runnable接口
- 重写run()方法
- 需要执行的代码写在方法体中
- 实例化Thread类,并传入Runnable接口实现类的实例,并调用start()方法
- new Thread(new ThreadCreate2()).start();
public class ThreadCreate2 implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + ": <子线程>-启动");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(Thread.currentThread().getName() + ": <子线程>-结束");
}
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName() + ": <主线程>-启动");
new Thread(new ThreadCreate2()).start();
new Thread(new ThreadCreate2()).start();
new Thread(new ThreadCreate2()).start();
System.out.println(Thread.currentThread().getName() + ": <主线程>-结束");
}
3. 匿名内部类实现Runnable接口
这种方式属于方法2的变体,在构造Thread类时传入一个Runnable实例,并实现run()方法即可
private static void main(String[] args) {
System.out.println(Thread.currentThread().getName() + ": <主线程>-启动");
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + ": <子线程>-启动");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(Thread.currentThread().getName() + ": <子线程>-结束");
}
}).start();
System.out.println(Thread.currentThread().getName() + ": <主线程>-结束");
}
4. lambda表达式
这种方式属于方法3的变体
- new Thread(() -> { 方法内容…}).start;
private static void main(String[] args) {
System.out.println(Thread.currentThread().getName() + ": <主线程>-启动");
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + ": <子线程>-启动");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(Thread.currentThread().getName() + ": <子线程>-结束");
}).start();
System.out.println(Thread.currentThread().getName() + ": <主线程>-结束");
}
5. 实现Callable接口
不同:可以获取到返回值
- 实现Callable接口,泛型用于指定返回值的类型
- 实现call()方法
- 需要执行的代码写在方法体中
- 实例化FutureTask,并传入Callable接口实现类的实例,泛型用于指定返回值类型
- 实例化Thread类,并传入FutureTasks实例,并调用start()方法
- 调用FutureTask实例的get()方法,可以获得子线程返回值
分析:
Integer result = futureTask.get();
// 获取子线程返回值时,主线程会等待子线程任务结束
// 相当于:
LockSupport.park();
Integer result = futureTask.get();
LockSupport.unPark();
6. 线程池
- 创建线程池
ExecutorService executorService = Executors.newCachedThreadPool();
- 调用线程池的execute()方法,执行线程任务
executorService.execute(() -> {})
- 传入的内容可以是Runnable接口的实现,也可以是Callable接口的实现
- 线程池 - Runnable接口
public class ThreadCreate4 {
static ExecutorService executorService = Executors.newCachedThreadPool();
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName() + ": <主线程>-启动");
executorService.execute(() -> {
System.out.println(Thread.currentThread().getName() + ": <子线程>-启动");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(Thread.currentThread().getName() + ": <子线程>-结束");
});
System.out.println(Thread.currentThread().getName() + ": <主线程>-结束");
}
}
- 线程池 - Callable接口
public class ThreadCreate5 {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
FutureTask<Integer> futureTask = new FutureTask<>(() -> {
System.out.println(Thread.currentThread().getName() + ": <子线程>-启动");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(Thread.currentThread().getName() + ": <子线程>-结束,返回值:1");
return 1;
});
executorService.execute(futureTask);
try {
Integer result = futureTask.get();
System.out.println(Thread.currentThread().getName() + ": <主线程>-获取结果为" + result);
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
}
本文是原创文章,转载请注明来自 Lazyking.site
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果
Steam卡片