首页 > 编程语言 >Java创建线程的方式

Java创建线程的方式

时间:2024-08-15 21:50:31浏览次数:12  
标签:Java Thread 创建 MyCallable 线程 println public

1.继承Thread类

第一步,创建一个线程类并继承Thread类
第二步,重写run()方法,内部自定义线程执行体
第三步,创建自定义的线程类对象,调用start()方法,启动线程

示例代码如下

public class MyThread1 extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 5; i++){
            System.out.println("自定义线程"+i);
        }
    }

    public static void main(String[] args) {
        MyThread1 myThread1 = new MyThread1();
        myThread1.start();
        for (int i = 0; i < 10; i++){
            System.out.println("主线程"+i);
        }
    }
}

ps:为什么不直接调用run()方法而是选择start()方法呢?

调用run()方法

调用start()方法

由此可见
如果在main方法中调用run()方法,只有主线程一条执行路径,如果调用start()方法,子线程的执行路径就会与主线程分开,两者将会并行且交替执行

2.实现Runnable接口

相比于第一种方式,第二种的前两步基本与第一种相同,主要的区别在于第三步

第一步,创建一个线程类并实现Runnable接口
第二步,实现run()方法,内部自定义线程执行体
第三步,创建实现类的对象并将其作为参数放入Thread的构造方法中创建线程对象,调用start()方法,启动线程

代码示例如下

public class MyRunnable implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 5; i++){
            System.out.println("自定义线程"+i);
        }
    }
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread myThread = new Thread(myRunnable);
        myThread.start();
        for (int i = 0; i < 10; i++){
            System.out.println("主线程"+i);
        }
    }
}

ps:此处用到了代理的思想,我们自定义的MyRunnable是没有start()方法的,因此我们选择让Thread类去帮助我们实现,myThread即代理对象

3.实现Callable接口

相比上面两种创建线程的方式,通过Callable来实现的方式拥有了异常处理和返回值的能力

第一步,创建一个类并实现Callable接口,需要在此设置返回值的类型
第二步,重写call()方法,需要抛出异常
第三步,创建目标对象,MyCallable,这里我给了他一个构造方法,方便我们定位到对象
第四步,创建一个线程池,用来执行我们创建的线程,这里的3代表创建的线程池的一个容量

ps:newFixedThreadPool 为定长线程池,这里的3就是他的最大并发数,若线程数超出这个数量则需要在队列中等待。线程池有几种类型此处不过多赘述。

第五步,将我们创建好的线程对象通过线程池对象的submit()方法提交,在此之后线程池会安排我们的线程去执行,并将结果返回,我们使用Future创建对象进行接收。
第六步,我们可以通过Future对象的get()方法获取到每个线程的执行结果
第七步,使用线程池的shutdownNow()方法关闭我们的线程池服务

ps:一定不要忘记关闭服务

示例代码如下

public class MyCallable implements Callable<String> {
    
    int ID;//标记区分不同的线程对象
    //写一个构造方法
    public MyCallable(int ID) {
        this.ID = ID;
    }

    @Override
    public String call() throws Exception {
        //模拟线程处理任务
        Thread.sleep(1000);
        System.out.println("睡醒了-->"+ID);
        return "自定义线程执行完毕-->"+ID;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //创建线程对象1,2,3
        MyCallable myCallable1 = new MyCallable(1);
        MyCallable myCallable2 = new MyCallable(2);
        MyCallable myCallable3 = new MyCallable(3);
        //创建线程池对象,提供线程池服务
        ExecutorService service = Executors.newFixedThreadPool(3);
        //通过线程池对象提交我们创建好的线程对象,并且声明Future对象来接收返回值
        Future<String> future1 = service.submit(myCallable1);
        Future<String> future2 = service.submit(myCallable2);
        Future<String> future3 = service.submit(myCallable3);
        //输出返回值
        System.out.println(future1.get());
        System.out.println(future2.get());
        System.out.println(future3.get());
        //关闭线程池服务
        service.shutdownNow();
    }
}

创建线程的方法五花八门,我们只要掌握最基本的方法就可以,每个人都有自己的编码习惯,也有自己惯用的线程创建方法,但是都是基于我们所说的这三种方式去实现的。
关于那种方式最好,我更推荐大家用Runnable或者Callable,第一种方式了解就行,至于Runnable和Callable如何选择,则需要根据项目所需,按需取舍。
ps:如果有写的不对的地方,欢迎各位大佬反馈,谢谢!

标签:Java,Thread,创建,MyCallable,线程,println,public
From: https://www.cnblogs.com/zyyjgsj/p/18360712

相关文章

  • JavaSE基础知识分享(七)
    写在前面前面讲的是面向对象中的常用类部分,下面让我们来看看java中集合这部分的内容!在本文的最后给大家发一个题目,便于复习Java面向对象部分的知识!集合数据结构栈和队列数组和链表树哈希表图本部分知识太多,就不一一列举了。了解更多泛型泛型类格式......
  • Java学习的第二天
    今天接着上篇的Java内容继续。首先说一下开发Java的注意事项:1、Java开发是以.Java为拓展名,源文件的基本组成是类(class)。2、应用程序的执行入口是main()方法,且有固定的书写模式:publicstaticvoidmain(String[]args){...}.3、严格区分大小写。4、Java方法是以一条条语句......
  • gym创建环境、自定义gym环境
    环境:half_cheetah.pyfromosimportpathimportnumpyasnpfromgymnasiumimportutilsfromgymnasium.envs.mujocoimportMujocoEnvfromgymnasium.spacesimportBoxDEFAULT_CAMERA_CONFIG={"distance":4.0,}classMOHalfCheetahEnv(Mujoc......
  • 高级java每日一道面试题-2024年8月15日-设计模式篇-设计模式与面向对象原则的关系是什
    如果有遗漏,评论区告诉我进行补充面试官:设计模式与面向对象原则的关系是什么?我回答:在设计模式与面向对象原则的关系中,两者紧密相连且相互促进。面向对象的原则为设计模式的形成提供了理论基础和指导思想,而设计模式则是这些原则在特定问题域中的具体实践和实现方式。下......
  • Java集合框架
    常见的集合框架Java集合框架可以分为两大的支线:①、Collection,主要由List、Set、Queue组成:List代表有序、可重复的集合,典型代表就是封装了动态数组的ArrayList和封装了链表的LinkedListSet代表无序、不可重复的集合,典型代表就是HashSet和TreeSet;Queue代表队列,典型代表就......
  • java异常你了解多少
    一、知识点概述(1)异常:异常就是Java程序在运行过程中出现的错误。(2)异常由来:问题也是现实生活中一个具体事务,也可以通过java的类的形式进行描述,并封装成对象。其实就是Java对不正常情况进行描述后的对象体现。(3)JVM的默认处理方案把异常的名称,错误原因及异常出现的位置等......
  • Java Data解决报错过程记录
    [attendancewebservice][24-08-1519:01:03.199][b3960aea15204b76b7c838189c28d45d][10.129.1.238]DEBUG[Thread-10][ne.jdbc.spi.SqlExceptionHelper.logExceptions139]couldnotexecutequery[select*fromid_customerswhereuserid=?]java.sql.SQLExceptio......
  • java7
    一、内部类1.成员内部类在一个类的内部定义的普通类可以访问外部类的所有成员,包括私有成员需要一个外部类的实例来创建成员内部类的实例可以被修饰为public、private、protected或者默认2.静态内部类一个静态内部类是静态的成员类。不需要外部类的实例来创建静态内部类......
  • 20240815有名管道双端线程通信
    //端1#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<unistd.h>#include<string.h>#include<pthread.h>#include<errno.h>#include<......
  • Linux线程
    一、线程的基本操作pthread_create(pthread_t*thread,constpthread_attr_t*attr,void*(*start_routine)(void*),void*arg) :此函数用于创建新线程。thread 用于存储新创建线程的标识符,attr 可指定线程属性,start_routine 是线程执行的函数指针,arg 为传递给线程执行......