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

Java 创建线程的方法

时间:2023-10-26 12:55:19浏览次数:34  
标签:Java Thread 创建 util 线程 import new public

目录

Java 中创建线程有四种方式,分别是:

继承 Thread 类

  • 首先定义一个类来继承 Thread 类,重写 run 方法。

  • 然后创建这个子类对象,并调用 start 方法启动线程。

示例:

public class ThreadDemo1 extends Thread {
    @Override
    public void run() {
        while (true) {
            System.out.println("thread demo1 is running");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

测试代码:

public class MainThreadDemo {
    public static void main(String[] args) {
        new ThreadDemo1().start();
    }
}

实现 Runnable 接口

  • 首先定义一个类实现 Runnable 接口,并实现 run 方法。

  • 然后创建 Runnable 实现类对象,并把它作为 target 传入 Thread 的构造函数中

  • 最后调用 start 方法启动线程。

示例:

public class ThreadDemo2 implements Runnable {
    @Override
    public void run() {
        while (true) {
            System.out.println("thread demo2 is running");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

测试代码:

public class MainThreadDemo {
    public static void main(String[] args) {
        new Thread(new ThreadDemo2()).start();
    }
}

实现 Callable 接口,并结合 Future 实现

  • 首先定义一个 Callable 的实现类,并实现 call 方法。call 方法是带返回值的。

  • 然后通过 FutureTask 的构造方法,把这个 Callable 实现类传进去。

  • 把 FutureTask 作为 Thread 类的 target ,创建 Thread 线程对象。

  • 通过 FutureTask 的 get 方法获取线程的执行结果。

import java.util.concurrent.Callable;

public class ThreadDemo3 implements Callable<String> {
    @Override
    public String call() {
        for (int i = 0; i < 10; i++) {
            System.out.println("thread demo3 is running");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        return "success";
    }
}

测试代码:

public class MainThreadDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<String> task = new FutureTask<>(new ThreadDemo3());
        new Thread(task).start();
        String result = task.get();
        System.out.println(result);
    }
}

通过线程池创建线程

方式一:Runnable

  • 首先,定一个 Runnable 的实现类,重写 run 方法。

  • 然后创建一个拥有固定线程数的线程池。

  • 最后通过 ExecutorService 对象的 execute 方法传入线程对象。
    示例:

public class ThreadDemo4 implements Runnable {

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("[" + Thread.currentThread().getName() + "]:thread demo3 is running, " + i);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

}

通过线程池创建线程:

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class MainThreadDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
        ExecutorService executorService = new ThreadPoolExecutor(
                8, 16, 60, TimeUnit.SECONDS, new SynchronousQueue<>(), new ThreadPoolExecutor.CallerRunsPolicy()
        );

        for (int i = 0; i < 3; i++) {
            executorService.execute(new ThreadDemo4());
        }
        executorService.shutdown();
    }
}

这种方法有一个缺点,无法对执行线程的任务传参,也没办法获取线程执行后的返回值,因此,实际使用的时候,更多的场景是使用 CompletableFuture 类去创建线程任务。

方式二:CompletableFuture

  • 使用 CompletableFuture 类去创建线程任务。

  • 然后创建一个拥有固定线程数的线程池。

  • 最后通过 CompletableFuture.supplyAsync 方法创建线程任务。

定义一个 Task 类:

public class ThreadDemo4 {

    public String count(int start, int end) {
        for (int i = start; i < end; i++) {
            System.out.println("[" + Thread.currentThread().getName() + "]: thread demo3 is running, " + i);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        return "success";
    }
}

创建线程池:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class MainThreadDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
        ExecutorService executorService = new ThreadPoolExecutor(
                8, 16, 60, TimeUnit.SECONDS, new SynchronousQueue<>(), new ThreadPoolExecutor.CallerRunsPolicy()
        );
        List<CompletableFuture<String>> futureList = new ArrayList<>();
        List<String> results = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            int finalI = i;
            CompletableFuture<String> future = CompletableFuture
                    .supplyAsync(() -> new ThreadDemo4().count(finalI, finalI + 10), executorService)
                    .whenComplete((result, exception) -> {
                        results.add(result);
                    });
            futureList.add(future);
        }

        CompletableFuture.allOf(futureList.toArray(new CompletableFuture[0])).get(10, TimeUnit.MINUTES);
        executorService.shutdown();
        System.out.println(results);
    }
}

CompletableFuture 创建线程的时候,也是调用的ExecutorService.execute 方法创建线程任务,但是,CompletableFuture 会将线程封装为 AsyncSupply 对象,在执行结束后,保存线程的计算结果。


参考:

标签:Java,Thread,创建,util,线程,import,new,public
From: https://www.cnblogs.com/larry1024/p/17789035.html

相关文章

  • JAVASCRIPT 上传文件的几种方式
    方法1:使用ajax,通过formdata传参//注意:FormData只兼容到IE10varformData=newFormData();varfile=$('.import-file-btn').get(0).files[0];formData.append('file',file);formData.append('id',id);formData.append('name',name)......
  • vue3项目创建
    1.确保npm指令能够运行-官网下载nodejs Download|Node.js(nodejs.org) 安装完成后重启intellij2.终端输入npminstall-gcreate-vue3.终端输入create-vue新建vue项目根据需要设置功能,例:4.打开新建vue项目中的README,点击npminstall前的绿色箭头,在t......
  • Java 练习题03 String类
    1. 编写一个程序,将下面的一段文本中的各个单词的字母顺序翻转, "Tobeornottobe",将变成"oTebrotonoteb."。importjava.util.Arrays;publicclassTest08{publicstaticvoidmain(String[]args){Strings="Tobeornottobe";//1.将字符串切......
  • 如何在Ubuntu20.04.3机器上使用kvm创建CentOs7.9的虚拟机
    一、虚拟化背景因为产品在Ubuntu的环境上部署兼容性差,Ubuntu的实体机上还运行着其他系统没办法进行系统的更换重装,所以只能出此下策~二、开始搭建更新Ubuntu系统打开终端并通过如下命令更新本地的软件包索引$sudoaptupdate$sudoaptupgrade检查虚拟化是否开启在......
  • 基于nfs创建StorageClass
    系统Cetnos7kubernetesv1.28.0nfs外部制备器nfs-subdir-external-provisioner一、制备器选择1.每个StorageClass都有一个制备器(Provisioner),用来决定使用哪个卷插件制备PV,本文基于NFS搭建StorageClass,NFS没有内部制备器,但可以使用外部制备器。也有第三方存储......
  • java中jdk8新特性
    Java中Jdk8的新特性包括:Lambda表达式:Lambda表达式是推动Java8发布的最重要新特性,允许把函数作为一个方法的参数或者把代码看成数据,使代码更加简洁紧凑。新的日期API:引入新的日期API,提供更加便捷的日期处理方式。Optional:引入Optional类,可以用来表示值存在或不存在的情况。Base64:内......
  • java8之引入流
    1.filter(筛选):接受Lanbda,从流中排出某些元素2.map(提取):接受一个Lanbda,将元素转换成其他形式或提取信息3.limit(截断):截断流,使其元素不超过给定数量4.distinct:筛选掉重复的元素4.collect:将流转换为其他形式注:流只能消费一次5.使用Collection接......
  • Java Calendar类练习题(获取日期)
    1.获取当前对象的日期的100天前的日期packagezuoye;importjava.text.SimpleDateFormat;importjava.util.Calendar;importjava.util.Date;publicclassTest1_01{publicstaticvoidmain(String[]args){//1、获取当前对象的日期的100天前的日期Calendarc......
  • javac命令的理解
    javac是编译命令javacA.java-ddirclass-encodingutf-8javac-classpath/-cp依赖包的路径,需要用:拼接起来,例如egjavac-cpspark_2.11.jar;flink_1.12.jarB.java-d/testdir多个依赖包,windows下用;分号,linux下用:冒号拼接依赖的包windows本地试验javac-cpD:\test......
  • Java 练习题02 (包装类 (对字符串进行排序))
    有一个字符串“101,87,88,87,98”对数字由小到大排序。importjava.util.Arrays;publicclassDemo01{publicstaticvoidmain(String[]args){Stringspa="101,87,88,87,98";//1.分割每个数字String[]str=spa.split(",");//2.定义int类型数......