创建线程的方式

方式一:通过继承Thread类创建线程

1.定义Thread类的子类,并重写该类的run方法,该方法的方法体就是线程需要执行的任务,因此run()方法也被称为线程执行体
2.创建Thread子类的实例,也就是创建了线程对象
3.启动线程,即调用线程的start()方法
public class MyThread extends Thread{//继承Thread类
  public void run(){
  //重写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 {//实现Runnable接口
  public void run(){
  //重写run方法
  }
}

public class Main {
  public static void main(String[] args){
    //创建并启动线程
    MyThread2 myThread=new MyThread2();
    Thread thread=new Thread(myThread);
    thread().start();
    //或者 new Thread(new MyThread2()).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) {
        //lambda + 匿名runnable的方式
        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方法来获取线程执行结束后的返回值
/*
*
* 创建并得到线程的结果
* 实现 Callable 接口 + Future 的方式
* */
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 {
        //1、创建一个Callable
        MyCallable myCallable = new MyCallable();
        //2、创建一个FutureTask对象来接收返回值
        FutureTask<Integer> futureTask = new FutureTask<>(myCallable);
        //3、创建Thread
        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创建的线程池-》线程池大小可变
posted @   自由的天堂  阅读(59)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示