java多线程(一)-五种线程创建方式
简单使用示例
Java 提供了三种创建线程的方法:
- 通过实现 Runnable 接口;
- 通过继承 Thread 类本身;
- 通过 Callable 和 Future 创建线程。
还有
- 定时器
- 线程池
下面第一个类给出了四种创建方式,第二个类是定时器示例。
①
public class ThreadStartTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.print("主线程(main)0启动!");
//实例化线程对象
Thread_1 thread_1 = new Thread_1();
//调用start()方法开启线程,然后会自动调用run()方法
thread_1.start();
//将实现Runnable接口对象实例化提交给Thread构造器(构造方法)
Thread thread_2 = new Thread(new Thread_2());
thread_2.start();
//callable接口可以返回值,但必须用submit()提交
ExecutorService execu = Executors.newCachedThreadPool();
Future<String> result = execu.submit(new TastWithResult());
System.out.println(result.get());
execu.shutdown();
//线程池
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(new Thread_2());
exec.shutdown();
//main线程
for(int i=0;i<5;i++) {
//等同于Thread.sleep(2000);
TimeUnit.MILLISECONDS.sleep(2000);
System.out.print("0");
}
}
}
/**
* 继承Thread类,重写run方法
*/
class Thread_1 extends Thread {
@Override
public void run() {
System.out.print("线程1启动!");
for(int i=0;i<5;i++) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print("1");
}
}
}
/**
* 实现Runnable接口
*/
class Thread_2 implements Runnable{
@Override
public void run() {
System.out.print("线程2启动!");
for(int i=0;i<5;i++) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print("2");
}
}
}
class TastWithResult implements Callable<String> {
@Override
public String call() throws Exception {
return "可以返回值啦!";
}
}
②定时器Timer
public class TimerTest {
public static void main(String[] args) throws InterruptedException {
Timer timer = new Timer();
//前一次执行程序结束后 2000ms 后开始执行下一次程序(循环)
timer.schedule(new TimerTask(){
@Override
public void run(){
System.out.println("Task1");
}
},0,2000);
//延迟1000ms执行程序
timer.schedule(new TimerTask(){
@Override
public void run(){
System.out.println("Task2");
}
},1000);
//前一次程序执行开始 后 2000ms后开始执行下一次程序(循环)
timer.scheduleAtFixedRate(new TimerTask(){
@Override
public void run(){
System.out.println("Task3");
}
},0,2000);
Thread.sleep(10*1000);
timer.cancel();
}
}
如果你想详细的了解一下Timer内部实现,可以参考下面的文章
说明
在《阿里巴巴java开发手册中》有这样一条:
3. 【强制】线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。
说明:使用线程池的好处是减少在创建和销毁线程上所消耗的时间以及系统资源的开销,解决资源不足的问题。如果不使用线程池,有可能造成系统创建大量同类线程而导致消耗完内存或
者“过度切换”的问题。
所以建议使用线程池。
4. 【强制】线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样
的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
说明:Executors 返回的线程池对象的弊端如下:
1)FixedThreadPool 和 SingleThreadPool:
允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM。
2)CachedThreadPool 和 ScheduledThreadPool:
允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM。
又因为有该建议,所以需要对线程池稍微深入了解使用。可以参考下面这篇文章。
java多线程(一)-五种线程创建方式的更多相关文章
- Java多线程(五)线程的生命周期
点我跳过黑哥的卑鄙广告行为,进入正文. Java多线程系列更新中~ 正式篇: Java多线程(一) 什么是线程 Java多线程(二)关于多线程的CPU密集型和IO密集型这件事 Java多线程(三)如何 ...
- java多线程总结五:线程池的原理及实现
1.线程池简介: 多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力. 假设一个服务器完成一项任务所需时间为:T1 创 ...
- java多线程(1)---线程创建、start、run
线程创建.start.run 一.创建线程方式 java创建线程的方式,主要有三种:类Thread.接口Runnable.接口Callable. 1.Thread和Runnable进行比较 他们之间的 ...
- Java并发:五种线程安全类型、线程安全的实现、枚举类型
1. Java中的线程安全 Java线程安全:狭义地认为是多线程之间共享数据的访问. Java语言中各种操作共享的数据有5种类型:不可变.绝对线程安全.相对线程安全.线程兼容.线程独立 ① 不可变 不 ...
- Java中String两种不同创建方式的区别及intern的用法
一, Java有两种创建字符串的方式, String str1 = "abc"; String str2 = new String("abc"); 用双引号创建 ...
- java多线程(五)线程通讯
1.1. 为什么要线程通信 多个线程并发执行时,在默认情况下CPU是随机切换线程的,有时我们希望CPU按我们的规律执行线程,此时就需要线程之间协调通信. 1.2. 线程通讯方式 线程间通信常用方式如下 ...
- java 多线程之 interrupt()和线程终止方式
interrupt() 说明 interrupt()的作用是中断本线程. 本线程中断自己是被允许的:其它线程调用本线程的interrupt()方法时,会通过checkAccess()检查权限.这有可能 ...
- JAVA多线程学习五:线程范围内共享变量&ThreadLocal
一.概念 可以将每个线程用到的数据与对应的线程号存放到一个map集合中,使用数据时从这个集合中根据线程号获取对应线程的数据,就可以实现线程范围内共享相同的变量. 二.代码 Runnable中的run( ...
- Java多线程(五)——线程等待与唤醒
一.wait().notify().notifyAll()等方法介绍 在Object.java中,定义了wait(), notify()和notifyAll()等接口.wait()的作用是让当前线程进 ...
随机推荐
- 深入了解java虚拟机(JVM) 第九章 class文件结构及意义
Class文件是访问jvm的重要指令,学习了class文件能够更加深入的了解jvm的工作过程.本文只进行概况总结,要进行更加详细的学习class文件,可以参考:https://blog.csdn.ne ...
- “全栈2019”Java第九十章:内部类可以向上或向下转型吗?
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- JAVA中-面向网络编程---单层交互
面向网络编程---单层交互: 客户端说明: /* * 实现TCP客户端,链接到服务器 * 和服务器实现数据交互 * 实现TCP客户端的类 java.net.Scoket * 构造方法: * Socke ...
- angular核心原理解析1:angular自启动过程
angularJS的源代码整体上来说是一个自执行函数,在angularJS加载完成后,就会自动执行了. angular源代码中: angular = window.angular || (window ...
- 10分钟教你用Python打造天气机器人+关键字自动回复+定时发送
01 前言 Hello,各位小伙伴.自上次我们介绍了Python实现天气预报的功能以后,那个小程序还有诸多不完善的地方,今天,我们再次来完善一下我们的小程序.比如我们想给机器人发“天气”等关键字,它就 ...
- Laravel5.5 使用第三方Vendor添加注册验证码
Laravel5系列的验证码添加通用,使用第三方验证码即可完美实现.这里记录下具体步骤吧,以备不时之需. 第一步:使用composer 安装 验证码库 composer require mews/ca ...
- 解决无法运行Terminator出现以下问题: File "/usr/bin/terminator"...SyntaxError: invalid syntax
在安装或者启动Terminator时可能出现这个问题: lin@Dev:~$ terminator File "/usr/bin/terminator", line 123 exc ...
- h5 页面点击添加添加input框
h5 页面点击添加添加input框 前段时间有个需求,页面要能点击添加按钮控制input框的个数,当时感觉有点难,就没做,这两个又遇到了,没办法写了个简单的 效果图,加号增加,减号减少 直接上代码, ...
- vue-cli3 chainWebpack配置,去除打包后文件的预加载prefetch/preload(已解决)
//细节配置修改 chainWebpack: config => { console.log(config,'chainWebpack') // 移除 prefetch 插件 config.pl ...
- Mac下在Shell终端下使用open快速打开窗口文件夹
Ubuntu下可以使用nautilus打开,但是在Mac替代的是open. 打开当前路径的窗口 oepn . 打开其他窗口 open /dirname 其实open不只可以打开窗口,应用同样支持. 关 ...