一、继承Thread类
1.代码示例
public class Thread01 extends Thread {
// 线程执行的代码在run()方法中,执行完毕后,线程死亡
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "<我是子线程>");
try {
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "子线程执行完毕");
}
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName() + "我是主线程");
//启动线程调用start()方法而不是run()方法 调用start()后线程变为就绪状态,而不是运行状态,还需等待CPU调度运行
new Thread01().start();
new Thread01().start();
System.out.println("---主线程执行完毕---");
}
}
运行结果如下:
main我是主线程
---主线程执行完毕---
Thread-0<我是子线程>
Thread-1<我是子线程>
Thread-1子线程执行完毕
Thread-0子线程执行完毕
2.总结
可以看出,主线程是不需要等待子线程执行完再执行下面的程序,主线程执行完了子线程还在执行,因此,子线程报错是不会影响主线程的。
二、实现runable接口
1.代码示例
public class Thread02 implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "<我是子线程>");
}
public static void main(String[] args) {
System.out.println("主程序运行");
new Thread(new Thread02()).start();
new Thread(new Thread02()).start();
System.out.println("主程序运行结束---");
}
}
运行结果:
主程序运行
主程序运行结束---
Thread-0<我是子线程>
Thread-1<我是子线程>
三、使用匿名内部类
public class Thread02 implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "<我是子线程>");
}
public static void main(String[] args) {
System.out.println("主程序运行");
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "<我是子线程>");
}
}).start();
System.out.println("主程序运行结束---");
}
}
运行结果:
主程序运行
主程序运行结束---
Thread-0<我是子线程>
四、使用lambda表达式
public class Thread02 implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "<我是子线程>");
}
public static void main(String[] args) {
System.out.println("主程序运行");
new Thread(() -> System.out.println(Thread.currentThread().getName() + "<我是子线程>")).start();
System.out.println("主程序运行结束---");
}
}
运行结果:
主程序运行
主程序运行结束---
Thread-0<我是子线程>
五、使用callable和Future创建
1.简介
callable和future现成可以获取到返回的结果,底层是基于LockSupport,从JDK5就提供了Callable接口,该接口是Runable的增强版
2.代码实现
public class ThreadCallable implements Callable<Integer> {
/**
* 当前线程需要执行的代码,以及返回结果
* @return
* @throws Exception
*/
@Override
public Integer call() throws Exception {
System.out.println("子线程开始执行。。");
try {
Thread.sleep(3000);
} catch (Exception e) {
}
System.out.println(Thread.currentThread().getName()+":返回1");
return 1;
}
}
public class Thread03 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ThreadCallable threadCallable = new ThreadCallable();
FutureTask<Integer> futureTask = new FutureTask<>(threadCallable);
new Thread(futureTask).start();
Integer result = futureTask.get();
System.out.println(Thread.currentThread().getName()+","+result);
}
}
运行结果如下:
子线程开始执行。。
Thread-0:返回1
main,1
3.注意
futureTask能返回线程的结果其实在调用get()方法时,底层的LockSupport调用LockSupport.park()方法,使主线程挂起等待,等子线程运行完返回结果后,再由LockSupport.unpark()唤起主线程。在子线程未返回结果前,主线程是阻塞等待状态的。文章来源:https://www.toymoban.com/news/detail-618294.html
六、使用线程池例如Executor框架创建
public class Thread04 {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(() -> System.out.println("我是子线程"));
}
}
七、spring @Async异步注解
只需要在调用的方法上写上注释@Async即可,被@Async注释的方式是异步执行的,相当于主线程中会单独另起一个线程执行。文章来源地址https://www.toymoban.com/news/detail-618294.html
到了这里,关于java创建多线程的7种方式---代码详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!