方式一:通过继承Thread类创建线程
1.定义Thread类的子类,并重写该类的run方法,该方法的方法体就是线程需要执行的任务,因此run()方法也被称为线程执行体
2.创建Thread子类的实例,也就是创建了线程对象
3.启动线程,即调用线程的start()方法
public class MyThread extends Thread{
public void run(){
}
}
public class Main {
public static void main(String[] args){
new MyThread().start();
}
}
方式二:通过实现Runnable接口创建线程
1.定义Runnable接口的实现类,一样要重写run()方法,和第一种方式一样,这里的run()方法也是线程的执行体
2.创建Runnable实现类的实例,并用这个实例作为Thread的target来创建Thread对象,这个Thread类才是真正的线程对象
3.依然是通过调用线程对象的start方法来启动线程
public class MyThread2 implements Runnable {
public void run(){
}
}
public class Main {
public static void main(String[] args){
MyThread2 myThread=new MyThread2();
Thread thread=new Thread(myThread);
thread().start();
}
}
匿名内部类的方式创建
public class ThreadDemo8 {
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程名:" +
Thread.currentThread().getName());
}
});
thread.start();
}
lambda + 匿名runnable的方式
public class ThreadDemo9 {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println("线程名:" +
Thread.currentThread().getName());
});
thread.start();
}
}
方式三:使用Callable和Future来创建线程
和Runnable接口不一样,Callable接口提供了一个call()方法来作为线程的执行体,call()方法比run()方法功能要更加强大,call()方法可以有返回值,call()方法可以声明抛出异常(前两种如果要抛异常只能通过try,catch来实现)。
1.创建Callable接口的实现类,并实现call()方法,然后创建该类的实例
2.使用Future Task类来包装Callable对象。该FutureTask对象封装了Callable对象的call()方法的返回值
3.使用FutureTask对象作为Thread对象的target创建并启动线程(因为FutureTask实现了Runnable接口并在重写的run方法中执行call方法)
4.调用FutureTask对象的get方法来获取线程执行结束后的返回值
public class ThreadDemo9 {
static class MyCallable implements Callable<Integer>{
@Override
public Integer call() throws Exception {
int num = new Random().nextInt(10);
System.out.println("子线程:" +
Thread.currentThread().getName() + ",随机数" +num);
return num;
}
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyCallable myCallable = new MyCallable();
FutureTask<Integer> futureTask = new FutureTask<>(myCallable);
Thread thread = new Thread(futureTask);
thread.start();
int result = futureTask.get();
System.out.println(String.format("线程名:%s,得到的数字:%d",
Thread.currentThread().getName(),result));
}
}
方法4:通过线程池来创建线程
注意:ExecutorService es = Executors.newFixedThreadPool(30);
ExecutorService es = Executors.newCachedThreadPool();
FixedThreadPool创建的线程池-》用户可以指定线程池大小,但指定了就不可变
CachedThreadPool创建的线程池-》线程池大小可变
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)