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()的作用是让当前线程进 ...
随机推荐
- 【Oracle 12c】最新CUUG OCP-071考试题库(56题)
56.(14-14) choose the best answer: You need to create a table with the following column specificatio ...
- win10开始菜单任务栏点击无反应
win+r,输入powershell,确定,输入Stop-Process -Name explorer,回车(这行代码是结束explorer进程,结束后它会自动重启)
- java简单正则验证手机号
import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @Title:Tadesfza * @Description ...
- HI~
我是一只来自青岛某鶸校的蒟蒻,很高兴能认识各位,本人水平有限,文章中的不足之处,希望大家不吝赐教 我的邮箱是zhenshiluosuo@gmail.com 微信clearsummerday 联系时烦请 ...
- robot framework学习笔记之一 资源文件(Resource)和外部资源(External Resources)
一.资源文件(Resource) 测试套件主要是存放测试案例,资源文件主要是用来存放用户关键字. 添加资源 在目录型的Project/Test Suite下单击鼠标右键,选择『New Resou ...
- 解决org.apache.lucene.store.AlreadyClosedException: this Directory is closed
在Lucene中,关闭一个IndexWriter时抛出AlreadyClosedException异常: org.apache.lucene.store.AlreadyClosedException: ...
- Linux(Ubuntu)配置问题集
Cannot set LC_CTYPE to default locale: No such file or directory 安装Ubuntu Server版本(不带桌面环境)时,如果安装时的语言 ...
- java 实现七大基本排序算法
一. 选择排序 /** * 选择排序: int arr[] = { 5, 6, 2, 7, 8, 6, 4 }; * * 第0趟 5 2 6 7 6 4 8 第1趟 2 5 6 6 4 7 8 第2趟 ...
- 1.由于测试某个功能,需要生成500W条数据的txt,python代码如下
txt内容是手机号,数量500W,采用python代码生成,用时60S,本人技能有限,看官如果有更快的写法,欢迎留言交流. import random f = open("D:\\data. ...
- RocketMQ之NameServer学习笔记
org.apache.rocketmq.namesrv.NamesrvController NameserController,NameServer的核心控制类. 1.1 NamesrvConfig ...