程序员:java中直接或间接创建线程的方法总结
在java开发中,经常会涉及多线程的编码,那么通过直接或间接创建线程的方法有哪些?现整理如下:
1、继承Thread类,重写run()方法
class Worker extends Thread {
@Override
public void run() {
System.out.println("Code run in a sub thread!");
}
}
public class CreateThreadTester {
public static void main(String[] args) throws InterruptedException {
Thread t = new Worker();
t.start();
t.join();
}
}
2、实现Runnable接口,重写run()
class Worker implements Runnable {
@Override
public void run() {
System.out.println("Code run in a sub thread!");
}
}
public class CreateThreadTester {
public static void main(String[] args) throws InterruptedException {
Runnable task = new Worker();
Thread t = new Thread(task);
t.start();
t.join();
}
}
3、实现Callable接口,重写call()
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
class Worker implements Callable<Integer> {
@Override
public Integer call() {
System.out.println("Code run in a sub thread!");
return Integer.valueOf(10);
}
}
public class CreateThreadTester {
public static void main(String[] args) throws InterruptedException, ExecutionException {
Callable<Integer> thread = new Worker();
FutureTask<Integer> task = new FutureTask<Integer>(thread);
Thread t = new Thread(task);
t.start();
System.out.println("Thread return value:" + task.get());
}
}
4、使用定时器
(1)基于类java.util.Timer和重写TimerTask的run()执行定时任务
示例代码如下:
import java.util.Timer;
import java.util.TimerTask;
class Worker extends TimerTask {
@Override
public void run() {
System.out.println("Code run in a sub thread!");
}
}
public class CreateThreadTester {
public static void main(String[] args) {
Timer timer = new Timer();
TimerTask task = new Worker();
timer.schedule(task, 0);
}
}
(2) 基于java.util.concurrent.Executors.newSingleThreadScheduledExecutor()执行定时任务
示例代码如下:
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ThreadScheduledExecutorTester01 {
private static ThreadLocal<SimpleDateFormat> dateFormat = new ThreadLocal<SimpleDateFormat>() {
public SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
}
};
public static void main(String[] args) {
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
service.schedule(new Runnable() {
@Override
public void run() {
System.out.println(dateFormat.get().format(new Date()) + " -- 11111111111111");
}
}, 2, TimeUnit.SECONDS);
service.schedule(new Runnable() {
@Override
public void run() {
System.out.println(dateFormat.get().format(new Date()) + " -- 22222222222222222222");
}
}, 2, TimeUnit.SECONDS);
service.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println(dateFormat.get().format(new Date()) + " -- 3333333333333333333333");
}
}, 1, 5, TimeUnit.SECONDS);
}
}
5、使用java.util.concurrent.Executors工厂类
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class Worker implements Runnable {
@Override
public void run() {
System.out.println("Code run in a sub thread!");
}
}
public class CreateThreadTester {
public static void main(String[] args) {
ExecutorService service = Executors.newSingleThreadExecutor();
Runnable command = new Worker();
service.execute(command);
}
}
Executors 的工具类可以创建三种类型的普通线程池:
固定大小的线程池:Executors.newFixedThreadPool(n)
单线程池:Executors.newSingleThreadExecutor()
缓存线程池:Executors.newCachedThreadPool()
当提交任务速度高于线程池中任务处理速度时,缓存线程池会不断的创建线程。 适用于提交短期的异步小程序,以及负载较轻的服务器,而负载相对较重的服务器应使用固定大小的线程池。
6、Spring中使用@EnableAsync和@Async注解
在pom.xml文件中配置spring-boot-starter依赖:
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
示例代码如下:
import java.util.concurrent.Executor;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
@Service
class AsyncService {
@Async
public void testAsync_1() {
System.out.println("testAsync_1 is running, thread :" + Thread.currentThread().getName());
}
@Async
public void testAsync_2() {
System.out.println("testAsync_2 is running, thread :" + Thread.currentThread().getName());
}
}
@Configuration
@ComponentScan("com.tang.spring")
@EnableAsync
class Config implements AsyncConfigurer {
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(2);
taskExecutor.setMaxPoolSize(2);
taskExecutor.setQueueCapacity(2);
taskExecutor.initialize();
return taskExecutor;
}
}
public class SpringApplicationTester {
public static void main(String[] args) {
AbstractApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
AsyncService bean = context.getBean(AsyncService.class);
bean.testAsync_1();
bean.testAsync_2();
}
}
今天就先介绍到这里,后面继续整理,持续更新。。。
程序员:java中直接或间接创建线程的方法总结的更多相关文章
- 【Java 线程的深入研究1】Java 提供了三种创建线程的方法
Java 提供了三种创建线程的方法: 通过实现 Runnable 接口: 通过继承 Thread 类本身: 通过 Callable 和 Future 创建线程. 1.通过实现 Runnable 接口来 ...
- 黑马程序员——JAVA基础之抽象和接口 , 模版方法设计模式
------- android培训.java培训.期待与您交流! ---------- 抽象定义: 抽象就是从多个事物中将共性的,本质的内容抽取出来. 例如:狼 ...
- 线程 学习教程(一): Java中终止(销毁)线程的方法
结束线程有以下三种方法:(1)设置退出标志,使线程正常退出,也就是当run()方法完成后线程终止 (2)使用interrupt()方法中断线程 (3)使用stop方法强行终止线程(不推荐使用,Thre ...
- 五年.net程序员Java学习之路
大学毕业后笔者进入一家外企,做企业CRM系统开发,那时候开发效率最高的高级程序语言,毫无疑问是C#.恰逢公司也在扩张,招聘了不少.net程序员,笔者作为应届生,也乐呵呵的加入到.net程序员行列中. ...
- Java中带包(创建及引用)的类的编译
Java中带包(创建及引用)的类的编译与调试 java源程序的编译大家都知道,也就是cmd中到源文件所在目录下javac **.java即可,当程序中有包声明还能简简单单的直接javac **.jav ...
- Java并发编程:如何创建线程?
Java并发编程:如何创建线程? 在前面一篇文章中已经讲述了在进程和线程的由来,今天就来讲一下在Java中如何创建线程,让线程去执行一个子任务.下面先讲述一下Java中的应用程序和进程相关的概念知识, ...
- java并发编程:如何创建线程
原文:http://www.cnblogs.com/dolphin0520/p/3913517.html 一.Java中关于应用程序和进程相关的概念 在Java中,一个应用程序对应着一个JVM实例(也 ...
- Java中Date和Calender类的使用方法
查看文章 Java中Date和Calender类的使用方法 2009-10-04 20:49 Date和Calendar是Java类库里提供对时间进行处理的类,由于日期在商业逻辑的应用中占据着 ...
- 【转】Java并发编程:如何创建线程?
一.Java中关于应用程序和进程相关的概念 在Java中,一个应用程序对应着一个JVM实例(也有地方称为JVM进程),一般来说名字默认是java.exe或者javaw.exe(windows下可以通过 ...
随机推荐
- robot_framework + selenium + 上传本地文件+win7 32位
1.下载与安装AutoIt v3 地址链接:http://pan.baidu.com/s/1hqsDFBA,我自己是32位的系统,用这个运行可以 2.安装完成后,如下图所示 3. AutoIt Wi ...
- 吴裕雄--天生自然java开发常用类库学习笔记:System类
public class SystemDemo01{ public static void main(String args[]){ long startTime = System.currentTi ...
- writeObiect与序列化反序列化
在写仿QQ聊天工具中,客户端与服务端之间的通信一开始是采用的是InputStream和OutputStream,这导致在数据传输过程中,登录信息,注册信息等难以区分,这时我给传输的数据加了标识来分辨信 ...
- NO14 快照-克隆-必须掌握的Linux目录结构
壹 VMware克隆,快照讲解及相应问题讲解: ·快照:比喻:假设把人生作一个快照.1岁10岁20岁6无限还原到前一个设置的节点. ·克隆学习一般用链接克隆,不另外占用磁盘,但是依赖本体虚拟机.完整 ...
- redis学习(五)
一.Redis 发布订阅 1.Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. 2.Redis 客户端可以订阅任意数量的频道. 比如你订阅 ...
- Acwing198 反素数
原题面:https://www.acwing.com/problem/content/200/ 题目大意:对于任何正整数x,其约数的个数记作g(x),例如g(1)=1.g(6)=4.如果某个正整数x满 ...
- Golang函数-不定参函数
Golang函数-不定参函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.
- C++ 非白名单程序间接启动
主要的思路是不能用不受信任的程序直接参与创建进程,而是间接启动目标进程.比如你可以把目标程序创建快捷方式,然后设置快捷键.然后向桌面发快捷键的按键消息,目标程序就会被桌面程序启动.
- CentOS7基于http方式搭建本地yum源
1.创建yum软件保存目录[root@localhost ~]# mkdir -p /www/share/yum 2. 修改yum配置文件先备份yum配置文件,修改yum配置文件中yum软件包保存目录 ...
- Python基础笔记:使用dict和set
dict 就和 C语言中的 map 的作用一样.查找非常快,以空间换时间! dict的使用: >>> d={'Mike':66,'Bob':77,'John':88} #定义一个di ...