java创建线程方式
2024-09-04 12:04:38
1.继承Thread类
public class ThreadCreator extends Thread{ public static void main(String[] args) {
//第一种方式:
ThreadCreator creator = new ThreadCreator();
Thread thread = new Thread(creator,"线程1");
thread.start();
//第二种方式:
Thread thread = new ThreadCreator();
thread.start();
//第三种方式:
new ThreadCreator().start();
} @Override
public void run() {
System.out.println(Thread.currentThread().getName() + "run");
}
}
2.实现Runnable接口
public class ThreadCreator implements Runnable{ public static void main(String[] args) {
ThreadCreator creator = new ThreadCreator();
Thread thread = new Thread(creator,"线程1");
thread.start();
} @Override
public void run() {
System.out.println(Thread.currentThread().getName() + "run");
}
}
3.实现Callable接口,与Runnable的区别:
1.Callable执行call()方法,具有返回值,通过使用FutureTask实例对象的get()方法获取,需要做异常处理。 Runnable执行run()方法,无返回值。
2.异常处理部分:run()方法遇到异常线程终止执行,挂起。call()方法可以捕捉异常处理后继续执行(此处说明是非执行逻辑部分异常)。
public class ThreadCreator implements Callable<Integer> { public static void main(String[] args) throws ExecutionException, InterruptedException {
ThreadCreator creator = new ThreadCreator();
FutureTask futureTask = new FutureTask(creator);
Thread thread = new Thread(futureTask,"线程");
thread.start();
System.out.println(futureTask.get());
} @Override
public Integer call() {
return 1024;
}
}
4.线程池ExecutorService
public class ThreadCreator{ static ExecutorService service = Executors.newFixedThreadPool(5); public static void main(String[] args) throws ExecutionException, InterruptedException {
//execute无返回值
service.execute(new ThreadTask(1,"1"));
//submit有返回值
Future<Integer> result = service.submit(new ThreadTaskCall());
System.out.println(result.get());
service.shutdownNow();
}
static class ThreadTask implements Runnable{
private int param1;
private String param2;
public ThreadTask(int param3,String param4){
this.param1 = param3;
this.param2 = param4;
}
@Override
public void run() {
System.out.println(param1+param2);
}
} static class ThreadTaskCall implements Callable<Integer>{
@Override
public Integer call() throws Exception {
return 1024;
}
}
}
线程池中submit和execute的区别:
① 可接受的任务类型不一样:execute只能接受Runnable任务,submit还可以接受Callable任务。
② 返回值:execute无返回值,任务一旦提交,无法在当前线程中监控执行结果。submit有一个Future类型的返回值,用来接收返回值或响应异常。通过get()方法获取。
submit底层还是调用的execute,只是在此基础上用future封装了一层,并将执行过程中产生的异常全部封装在一个变量中:
public void run() {
if (state != NEW ||
!UNSAFE.compareAndSwapObject(this, runnerOffset,
null, Thread.currentThread()))
return;
try {
Callable<V> c = callable;
if (c != null && state == NEW) {
V result;
boolean ran;
try {
result = c.call();
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
if (ran)
set(result);
}
} finally {
runner = null;
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
protected void setException(Throwable t) {
if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
outcome = t;
UNSAFE.putOrderedInt(this, stateOffset, EXCEPTIONAL); // final state
finishCompletion();
}
}
另外,spring中的schedule注解借鉴使用了submit的处理方式。
5.匿名内部类
public class ThreadCreator { public static void main(String[] args) { //继承Thread类
new Thread() {
@Override
public void run() {
System.out.println("extends Thread Class!");
}
}.start();
//实现Runnable接口
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("implement Runnable!");
}
}).start();
//实现Callable接口
new Thread(new FutureTask<Integer>(new Callable() {
@Override
public Integer call() throws Exception {
return 1024;
}
})).start();
//lambda表达式
new Thread(() -> System.out.println("execute single code")).start();
new Thread(() -> {
System.out.println("execute multiple code");
}).start();
}
}
lambda线程池:
public class ThreadCreator { static ExecutorService service = Executors.newFixedThreadPool(5); static List list = new ArrayList(); public static void main(String[] args) {
service.execute(() -> execute()); //无返回值
Future future = service.submit(() -> execute()); //有返回值
list.add(future);
} public static void execute() {
//do something
}
}
最新文章
- 个人作业-Week1
- Createjs学习一
- GNOME编辑器--gedit 构建基本脚本
- 日常笔记 ---- 图形学-Frenel函数材质球实现方式
- 添加和删除hadoop集群中的节点
- 多个相同name的文本输入框,输入其中一个后,使剩下的不能输入值
- Javascript -- Math.round()、Math.ceil()、Math.floor()、parseInt去小数取整总结
- 第三篇:数据仓库系统的实现与使用(含OLAP重点讲解)
- base64位加密解密
- 关于U3D的.SDK对接
- 将 ASP.NET Core 2.0 项目升级至 ASP.NET Core 2.1.3X
- ubuntu安装启动redis
- BugPhobia开发篇章:Beta阶段第I次Scrum Meeting
- nginx根据http_user_agent防DDOS
- DataTableExtensions
- 微信退款证书使用c#
- hive与hbase的整合
- 浅谈kmp
- linux下core dump
- ubuntu14.04中安装jdk
热门文章
- 吴裕雄 Bootstrap 前端框架开发——简介
- Cisco AP-如何调整LAP信道
- Win Tomcat8 占用内存过高
- Tensorflow机器学习入门——ModuleNotFoundError: No module named &#39;tensorflow.keras&#39;
- 当在命令行中执行virtualenv venv时报此错误:&#39;utf-8&#39; codec can&#39;t decode byte 0xd5 in position 38: invalid continuation by
- JavaScript图形实例:圆内螺线
- vs下载为0的问题
- Flask程序相关配置加载的三种方式
- 【规范建议】服务端接口返回字段类型与iOS端的解析
- 【原】简单shell练习(四)