1、继承Thread类方式

这种方式适用于执行特定任务,并且需要获取处理后的数据的场景。

举例:一个用于累加数组内数据的和的线程。

public class AdditionThread extends Thread {
private int sum = 0;
private int[] nums;

public AdditionThread(int[] nums, String threadName) {
super(threadName);
this.nums = nums;
}

@Override
public void run() {
for (int num : nums) {
sum += num;
}
}

public int getSum() {
return sum;
}
}

调用方式:

public class Main {
public static void main(String[] args) throws InterruptedException {
int[] nums = {10, 12, 15, 200, 100};
AdditionThread thread = new AdditionThread(nums, "AdditionThread");
thread.start();
thread.join();

System.out.println("sum=" + thread.getSum());
}
}

2、Runnable 接口方式

定义一个实现Runnable接口的类,或者直接创建一个匿名内部类,并覆盖 run() 方法。最后作为参数传给Thread的构造函数。

public class Main {
public static void main(String[] args) {
// 自定义的 Runnable
Runnable runnable = new MyRunnable();
Thread thread = new Thread(runnable, "Runnable-Thread");
thread.start();

// 自定义匿名内部类
new Thread(() -> {
System.out.println("Inner class");
}).start();
}

static class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("MyRunnable");
}
}
}

3、 Callable 接口方式

Callable 接口与 Runnable 接口的区别:

(1)Callable 的方法为call(),Runnable的方法为run()。

(2)Callable 的方法由返回值,Runnable 没有。

(3)Callable 的方法声明的Exception,Runnable的没有。

public class Main {
public static void main(String[] args) {
MyCallable myCallable = new MyCallable();
FutureTask<String> task = new FutureTask<>(myCallable);
Thread thread = new Thread(task, "FutureTask");
thread.start();
try {
// 通过get方法获取返回值
String result = task.get();
System.out.println(result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}

static class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
// 模拟超时操作
Thread.sleep(1000);
return "OK";
}
}
}

4、线程池方式

我们可以通过 ThreadPoolExecutor 类的构造函数来创建线程池,也可以通过Executors工厂方法来创建,如

// 创建固定线程数的线程池
Executors.newFixedThreadPool();
// 创建只有一个核心线程的线程池
Executors.newSingleThreadExecutor();
// 创建一个没有核心线程,但可以缓存线程的线程池
Executors.newCachedThreadPool();
// 创建一个适用于执行定时任务的线程池
Executors.newScheduledThreadPool();

在创建线程池时,最好传入 ThreadFactory 参数,指定线程池所创建线程的名称。这样有利于分析定位可能存在的问题。

public class Main {
private static final ExecutorService SERVICE =
Executors.newFixedThreadPool(5, new BasicThreadFactory("My-Thread"));

public static void main(String[] args) {
// 打印线程的名字
System.out.println("main thread name:" + Thread.currentThread().getName());
SERVICE.execute(() -> {
System.out.println("Hello thread pool.");
// 打印线程池里的线程的名字
System.out.println("thread name:" + Thread.currentThread().getName());
});
}

static class BasicThreadFactory implements ThreadFactory {
private final AtomicInteger threadNumber = new AtomicInteger(0);
private final String basicName;

public BasicThreadFactory(String basicName) {
this.basicName = basicName;
}

@Override
public Thread newThread(Runnable runnable) {
Thread thread = new Thread(runnable);
String name = this.basicName + "-" + threadNumber.incrementAndGet();
thread.setName(name);
return thread;
}
}
}

【Java】线程的创建方式的更多相关文章

  1. Java线程的创建方式三:Callable(四)

    一.Java实现多线程的三种方式 方式一:继承Thread类: public class Test extends Thread { public static void main(String[] ...

  2. Java多线程——线程的创建方式

    Java多线程——线程的创建方式 摘要:本文主要学习了线程的创建方式,线程的常用属性和方法,以及线程的几个基本状态. 部分内容来自以下博客: https://www.cnblogs.com/dolph ...

  3. Java线程:创建与启动

    Java线程:创建与启动 一.定义线程   1.扩展java.lang.Thread类.   此类中有个run()方法,应该注意其用法: public void run() 如果该线程是使用独立的 R ...

  4. 漫谈并发编程(二):java线程的创建与基本控制

    java线程的创建 定义任务           在java中使用任务这个名词来表示一个线程控制流的代码段,用Runnable接口来标记一个任务,该接口的run方法为线程运行的代码段. public ...

  5. JAVA - 线程从创建到死亡的几种状态都有哪些?

    JAVA - 线程从创建到死亡的几种状态都有哪些? 新建( new ):新创建了一个线程对象. 可运行( runnable ):线程对象创建后,其他线程(比如 main 线程)调用了该对象 的 sta ...

  6. Java并发编程(01):线程的创建方式,状态周期管理

    本文源码:GitHub·点这里 || GitEE·点这里 一.并发编程简介 1.基础概念 程序 与计算机系统操作有关的计算机程序.规程.规则,以及可能有的文件.文档及数据. 进程 进程是计算机中的程序 ...

  7. Java 线程的创建和启动

    Java 使用 Thread 类代表线程,所有的线程对象都必须是 Thread 类或其子类的实例.每个线程的作用是完成一定的任务,实际上就是执行一段程序流(一段顺序执行的代码). Java 使用线程执 ...

  8. Java之多线程创建方式

    多线程的由来 我们在之前,学习的程序在没有跳转语句的前提下,都是由上至下依次执行,那现在想要设计一个程序,边打游戏边听歌,怎么设计?要解决上述问题,咱们得使用多进程或者多线程来解决. 多线程的好处: ...

  9. Java线程之创建线程

    翻译自:https://www.journaldev.com/1016/java-thread-example 进程 进程是一个自包含的执行环境,它可以被看成一个程序或应用程序.然而一个应用程序本身包 ...

  10. 【JAVA并发第二篇】Java线程的创建与运行,线程状态与常用方法

    1.线程的创建与运行 (1).继承或直接使用Thread类 继承Thread类创建线程: /** * 主类 */ public class ThreadTest { public static voi ...

随机推荐

  1. 一个漂亮的JavaScript“警告”替代品

    下载 一个漂亮的JavaScript"警告"替代品 安装 $ npm安装-节省sweetalert 使用 从"sweetalert"进口swal; 横波测井(& ...

  2. RHSA-2019:0201-低危: systemd 安全更新

    [root@localhost ~]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) 修复命令: 使用root账号登陆She ...

  3. 2017年 实验三 C2C模拟实验

    [实验目的] 掌握网上购物的基本流程和C2C平台的运营 [实验条件] ⑴.个人计算机一台 ⑵.计算机通过局域网形式接入互联网. (3).奥派电子商务应用软件 [知识准备] 本实验需要的理论知识:C2C ...

  4. python接口测试之读取配置文件

    1.python使用自带的configparser模块用来读取配置文件,配置文件可以为.conf或.ini结尾 在使用前需要先安装该模块,使用pip安装即可 2.新建一个名为a.conf的配置文件 a ...

  5. sublime破解 mac版本下载

    date: "2020-10-18T10:03:01+08:00" title: "sublime破解 mac版本下载" tags: ["sublim ...

  6. Python之for循环和列表

    for循环: 有限循环 基本语法: for 变量 in 可迭代对象: 循环体 也可使用break,continue,for else list列表初识: 列表可放任意数据类型:[int,str,boo ...

  7. Java9系列第7篇:Java.util.Optional优化与增强

    我计划在后续的一段时间内,写一系列关于java 9的文章,虽然java 9 不像Java 8或者Java 11那样的核心java版本,但是还是有很多的特性值得关注.期待您能关注我,我将把java 9 ...

  8. Kubernetes 使用 ceph-csi 消费 RBD 作为持久化存储

    原文链接:https://fuckcloudnative.io/posts/kubernetes-storage-using-ceph-rbd/ 本文详细介绍了如何在 Kubernetes 集群中部署 ...

  9. Seaborn中几种作图方式

    趋势 sns.pointplot - 点图 ,比折线图好使 sns.lineplot - 折线图最适合显示一段时间内的趋势,多条线可以用来显示多个组中的趋势. 关系 - 可以使用许多不同的图表类型来理 ...

  10. Mybatis项目搭建

    MyBatis是一个优秀的持久层框架.原生的jdbc操作存在大量的重复性代码(如注册驱动,创建连接,创建statement,结果集检测等).框架的作用就是把这些繁琐的代码封装. MyBatis通过XM ...