如何创建线程

常用的创建线程的方法有三种:

  • 继承Thread类

  • 实现Runnable接口

  • 实现Callable接口

我们来说说继承Thread类 :

package lesson01;
​
public class Thread_Class  {
    public static void main(String[] args) {
        //创建子线程
        MyThread myThread = new MyThread();//创建一个线程的对象
        myThread.start();//开启子线程
        
        for (int i = 0; i < 100; i++) {
            System.out.println("执行了主线程");
        }
    }
}
class MyThread extends Thread{
    @Override
    public void run(){//子线程
        for (int i = 0; i < 100; i++) {
            System.out.println("执行了子线程");
        }
    }
}

创建线程的步骤:

  • 写一个类名叫MyThread的类继承Thread类,Thread是一个线程包下的已经被别人写好的类,MyThread则是我们创建的子线程要执行的类

  • 在MyThread里重写run()方法,@Override就是表示重写的意思

  • 然后我们在主程序里创建一个MyThread类的对象,我们要通过这个对象来开启线程

  • 我们通过start()的方法启动子线程

容易产生的疑惑:

为什么要重写run()方法?
  • 因为继承Thread父类里的run()方法没有我们要的功能

为什么不直接调用run()方法,而去调用start()方法?
  • 因为myThread.run()表示调用函数,没有开启线程

以上就是通过Thread类创建并启动线程的方法

实现Runnable接口:

package lesson01;
​
public class Runnable_Interface {
    public static void main(String[] args) {
        MyRunner myRunner = new MyRunner();
        new Thread(myRunner).start();
        
        for (int i = 0; i <1000 ; i++) {
            System.out.println("我是main主线程");
        }
    }
}
class MyRunner implements Runnable{
​
    @Override
    public void run() {
        for (int i = 0; i <1000 ; i++) {
            System.out.println("我是通过Runnable接口创建的子线程");
        }
    }
}
​

实现Runnable接口与继承Thread类的区别:

  • 你需要在创建线程对象(myRunner)以后再创建一个Thread类的对象,然后将Runnable实现类(MyRunner)的对象当作参数传入Thread对象,然后通过Thread对象来开启线程,至于为什么要这么搞,它使用到了一个叫“静态代理”的思想,我们会在下一篇文章讨论

new Thread(myRunner).start();//创建对象,调用方法一气呵成   
Thread thread = new Thread(myRunner);//一步步来,上面比较简洁
thread.start();

实现Callable接口:

package lesson01;
​
import java.util.concurrent.*;
​
public class Callable_Interface {
    public static void main(String[] args) throws ExecutionException,InterruptedException {
        MyOneCallable mc = new MyOneCallable();
        MyTwoCallable md = new MyTwoCallable();
        MyThreeCallable me = new MyThreeCallable();
​
        ExecutorService sc = Executors.newFixedThreadPool(3);//开启拥有三条线程的线程池
​
        Future<Boolean> sut = sc.submit(mc);//上交子线程并等待CPU调用 == 开启线程
        Future<Boolean> sut2 = sc.submit(md);//上交子线程并等待CPU调用 == 开启线程
        Future<Boolean> sut3 = sc.submit(me);//上交子线程并等待CPU调用 == 开启线程
​
        boolean result = sut.get();//获取返回值
        boolean result2 = sut2.get();//获取返回值
        boolean result3 = sut3.get();//获取返回值
​
        sc.shutdown();//关闭线程池,开启了就一定要关闭,又开又关,再开不难
    }
}
class MyOneCallable implements Callable<Boolean>{
​
    @Override
    public Boolean call() throws Exception {
        for (int i = 0; i < 1000; i++) {
            System.out.println("执行了Callable的第一个子线程");
        }
        return true;
    }
}
class MyTwoCallable implements Callable<Boolean>{
​
    @Override
    public Boolean call() throws Exception {
        for (int i = 0; i < 1000; i++) {
            System.out.println("执行了Callable的第二个子线程");
        }
        return true;
    }
}
class MyThreeCallable implements Callable<Boolean>{
​
    @Override
    public Boolean call() throws Exception {
        for (int i = 0; i < 1000; i++) {
            System.out.println("执行了Callable的第三个子线程");
        }
        return true;
    }
}
​

实现Callable接口创建线程与上面两种方式不同的是,他要创建一个线程池,通过submit()方法开启线程,完事儿以后还要关闭线程

以上就是创建线程的三种方法,逻辑相同,实际写的代码有所差异,Callable的代码看起来多是因为创建了三个子线程

由于cpu执行速度太快,所以我们才将循环的次数弄成1000,不然看不出来这三个线程是交替执行的

相关推荐

  1. 如何创建线

    2024-01-27 11:12:03       30 阅读
  2. springboot如何创建全局线

    2024-01-27 11:12:03       34 阅读
  3. 如何在C++中创建和管理线

    2024-01-27 11:12:03       17 阅读
  4. A类中创建posix线线如何通信

    2024-01-27 11:12:03       35 阅读
  5. Callable方式创建线

    2024-01-27 11:12:03       41 阅读
  6. 创建线的方式

    2024-01-27 11:12:03       13 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-27 11:12:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-27 11:12:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-27 11:12:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-27 11:12:03       18 阅读

热门阅读

  1. [GN] Vue3.2 快速上手 ---- 组件通信

    2024-01-27 11:12:03       35 阅读
  2. CF1029E Tree with Small Distances 题解

    2024-01-27 11:12:03       38 阅读
  3. TiDB中Table映射到KV

    2024-01-27 11:12:03       31 阅读
  4. nginx做盗链与防盗链配置

    2024-01-27 11:12:03       26 阅读
  5. 常用的gpt-4 prompt words收集8

    2024-01-27 11:12:03       26 阅读
  6. php 源码加密保护 bease方案

    2024-01-27 11:12:03       26 阅读
  7. android studio开发的一些问题

    2024-01-27 11:12:03       36 阅读
  8. CentOS 7.9 OS Kernel Update 3.10 to 4.19

    2024-01-27 11:12:03       29 阅读