首页 > 编程语言 >Java 创建多线程的三种方法

Java 创建多线程的三种方法

时间:2023-11-16 10:14:34浏览次数:39  
标签:Java Thread 主线 num 三种 线程 多线程 public

在Java中创建多线程,往往都要通过Thread类来实现,今天学习下Java中创建多线程的三种方法[1]。

1.继承Thread类

通过继承 Thread类 实现多线程。

主要方法:

  • 1.void run(), 线程开启后,方法将被调用执行
  • 2.void start(), 使此线程开始执行, Java虚拟机会调用run()方法

实现步骤:

  • 1.定义类,继承 Thread类
  • 2.重写 run() 方法
  • 3.创建多线程类对象
  • 4.通过实例方法 start() 启动线程

demo

public class MyThreadExtendsThread extends Thread {
    private int num;
    public MyThreadExtendsThread() {};

    public MyThreadExtendsThread(int num) {
        this.num = num;
    }

    @Override
    public void run() {
        for (int i = 0; i < num; i++) {
            System.out.println(Thread.currentThread().getName() + " 子线程:" + i);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new MyThreadExtendsThread();
        Thread t2 = new MyThreadExtendsThread(100000);

        t2.setDaemon(true); // true, 主线程结束,子线程也随之退出, false, 主线程结束后,子线程继续执行

        t1.start();
        t2.start();

        for (int i = 0; i < 10; i++) {
            System.out.println("主线程:" + i);
        }
        // 等待子线程完成任务
        Thread.sleep(10L);
        /*
        子线程:0
        子线程:1
        主线程:0
        子线程:2
        主线程:1
        主线程:2
        主线程:3
        主线程:4
        主线程:5
        主线程:6
        主线程:7
        子线程:3
        子线程:4
        子线程:5
        子线程:6
        子线程:7
        子线程:8
        子线程:9
        主线程:8
        主线程:9
         */
    }
}

2.实现Runnable接口

通过实现 Runnable接口 实现多线程。

主要方法:

  • 1.void run(),重写run方法

实现步骤:

  • 1.定义类,实现 Runnable 接口
  • 2.类中重写 run()方法
  • 3.创建多线程类对象
  • 4.创建 Thread 类对象,通过传入多线程类对象作为构造方法参数
  • 5.通过 Thread 类对象的 start 方法启动线程

demo

public class MyThreadImplementsRunnable implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println("子线程:" + i);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Runnable t1 = new MyThreadImplementsRunnable();
        new Thread(t1).start();

        for (int i = 0; i < 5; i++) {
            System.out.println("主线程:" + i);
        }

        Thread.sleep(1000L);
        /*
        子线程:0
        主线程:0
        主线程:1
        主线程:2
        主线程:3
        主线程:4
        子线程:1
        子线程:2
        子线程:3
        子线程:4
         */
    }
}

3.实现Callable接口

通过实现 Callable接口 实现多线程。

主要方法:

  • 1.V call(), 计算结果,如无,则抛出异常
  • 2.V get(), 如必要,等待计算完成,然后获取结果

实现步骤:

  • 1.定义类实现 Callable 接口
  • 2.在刚定义的类中重写 call()方法
  • 3.创建 MyThreadImplementsCallable 对象
  • 4.创建 Future 接口的实现类 FutureTask 对象,传入 MyThreadImplementsCallable 作为构造方法的参数
  • 5.创建 Thread 类对象,传入FutureTask作为构造方法参数
  • 6.启动线程
  • 7.如有需要,通过调用 get() 方法, 获取线程任务结束后的结果

demo

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class MyThreadImplementsCallable implements Callable {
    private int num;

    public MyThreadImplementsCallable(int num) {
        this.num = num;
    }

    @Override
    public String call() throws Exception {
        int sum = 0;

        for (int i = 0; i < num; i++) {
            sum += i;
        }

        return "线程求出 -> " + num + "之内的和为:" + sum;
    }

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        Callable callable = new MyThreadImplementsCallable(1000);
        // 创建未来任务实现Callable接口
        FutureTask<String> futureTask = new FutureTask<>(callable);
        new Thread(futureTask).start();

        // 获取线程任务结束后的结果
        String res = futureTask.get();
        System.out.println("res: " + res);
        // res: 线程求出 -> 1000之内的和为:499500
    }
}

4.方法对比

以下为多线程中类关系图:

image.png

从关系图中可知:

  • 三种方法实现多线程,都与Runnable接口有关
  • 从实现RUnnable接口的MyRunnable和MyCallable两种方法中,也都要通过Thread类来创建多线程

如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享[2]。

总结:

实现Runnable接口比继承Thread类所具有的优势:

1):适合多个相同的程序代码的线程去处理同一个资源

2):可以避免java中的单继承的限制

3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立

4):线程池只能放入实现Runablecallable类线程,不能直接放入继承Thread的类

参考:

标签:Java,Thread,主线,num,三种,线程,多线程,public
From: https://www.cnblogs.com/davis12/p/17835556.html

相关文章

  • 想快速进入人工智能领域的Java程序员?你准备好了吗?
    引言今天我们来探讨一下作为Java程序员,如何迅速融入人工智能的领域。,当前有一些流行的LLMs选择,例如ChatGPT、科大讯飞的星火、通义千问和文心一言等。如果你还没有尝试过这些工具,那么现在也不失为一个很好的机会,赶快体验一下吧。这些工具不仅能够为你的Java编程工作提供更多的可......
  • Java 多线程安全的使用小结
    在使用多线程进行编程的过程中,难免遇到共享资源读写问题,这是为了线程安全,一种思路就是使用锁来控制并发读写问题。在通过锁来实现并发安全中,常用的有以下几种:synchronized,对象锁ReentrantLock,重入锁ReentrantReadWriteLock,读写锁今天从使用的角度来看看这几种锁是如何使......
  • Java 线程池使用小结
    我们在使用多线程编程的时候,为何要用线程池呢?使用线程池的好处是什么呢?线程池有哪些使用场景?为何使用线程池?因为线程资源宝贵,不论创建新的线程还是销毁线程,都有相应的资源开销,比如在数据库连接方面,每个请求过来都是新建连接数据库的线程,请求少,资源开销总体不大,但也架不住请求一......
  • 最新版本的AndroidStudio新建Android项目时设置语言为java
    我们之前用AndroidStudio新建项目时是这样的 选择EmptyActivity,下一步 怎么没了语言选项了,java呢?改为EmptyViewsActivity这个就好了 ......
  • Java中的Comparator自定义排序
    需求:将指定数据中的数据,按照字母中包含的数字大小进行排序测试代码:publicstaticvoidmain(String[]args){List<String>list=newArrayList<>();list.add("QW34");list.add("QW21");list.add("QW12");list.add("QS34"......
  • 在 Angular 中,Controller 之间通信的方式主要有三种:作用域继承仅限于上下级之间的通信
    AngularJS中control间通信最好使用什么方式?A回调B全局变量C广播D函数调用正确答案:C在Angular中,Controller之间通信的方式主要有三种:1)作用域继承。利用子Controller控制父Controller上的数据。2)注入服务。把需要共享的数据注册为一个service,在需要的Controlle......
  • setTimeout 是浏览器环境提供的,JS 标准没有规定。不是JavaScript的全局函数,是浏览器(宿
    下列哪些函数是JavaScript的全局函数?AencodeURIBparseFloatCsetTimeoutDeval正确答案:ABD答案:A、B、D个人记忆方法:6(编码相关)+2(数据处理)+4(数字相关)+1(特殊)编码相关:escape()、unescape()、encodeURI()、decodeURI()、encodeURIComponent()、decodeURIComponent......
  • onclick="javascript:void(0)"就是行内javascript
    给网页添加JavaScript的方式有A使用script标签,将javascript代码写到之间B添加外部javascript文件C使用行内javascriptD使用@import引入javascript文件正确答案:ABCA正确。使用script标签,将javascript代码写到之间,例子:<scriptype="text/javascript">document.write("Hel......
  • java 继承中的访问特点已经方法的重构
    packagenet.elaina.a01oopextensdemo2;publicclassTest{publicstaticvoidmain(String[]args){//利用空参构造创建子类对象Ziz1=newZi();z1.ziShow();}}classFu{Stringname="Fu";}classZiextendsFu{......
  • Java方法01:什么是方法?
    一、何谓方法?1.System->类 out->对象println->方法2.方法的命名规则:首字母小写,后面是驼峰的命名规则publicclassDemo01{//main方法publicstaticvoidmain(String[]args){intsum=add(1,2);System.out.println(sum);}//加......