JUC–线程创建
线程创建有几种方式?你都会用吗?
方式一 通过继承Thread
class ExtendThread extends Thread{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"ti****** t");
}
}
public static void main(String[] args) {
for(int i=0;i<3;i++){
new Thread(()->{
new ExtendThread().run();
},String.valueOf(i)).start();
}
}
方式二 通过实现Runnable
class ExtendRunable implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"ti****** t");
}
}
public static void main(String[] args) {
for(int i=0;i<3;i++){
new Thread(()->{
new ExtendRunable().run();
},String.valueOf(i)).start();
}
}
方式三、四 通过实现Callable,使用线程池创建
与前两种相比,有返回值,并且可以异步延迟获取,需要借助futureTask
class ExtendCallable implements Callable<Integer>{
public ExtendCallable(){
System.out.println("生成子线程计算任务:t"+Thread.currentThread().getName());
}
@Override
public Integer call() throws Exception {
System.out.println("执行计算******start********");
for (int i = 0; i < 100; i++) {
}
//每次计算延迟5秒
try {
TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {e.printStackTrace();}
System.out.println("执行计算******end********");
return 100;
}
}
public static void main(String[] args) {
//需要FutureTask的支持 用于接收运算结果 也可以用用于闭锁
/**
* 1、多个并行任务同时计算,统计汇总结果
*/
// 建立任务集合
List<FutureTask<Integer>> taskList = new ArrayList<FutureTask<Integer>>();
// 建立线程池
ExecutorService exec = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
// 传入Callable对象建立FutureTask对象
FutureTask<Integer> ft = new FutureTask<Integer>(new ExtendCallable());
taskList.add(ft);
// 提交给线程池执行任务,也能够经过exec.invokeAll(taskList)一次性提交全部任务;
exec.submit(ft);
}
System.out.println("全部计算任务提交完毕, 主线程接着干其余事情!");
// 开始统计各计算线程计算结果
Integer totalResult = 0;
for (FutureTask<Integer> ft : taskList) {
try {
//FutureTask的get方法会自动阻塞,直到获取计算结果为止
totalResult = totalResult + ft.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
// 关闭线程池
exec.shutdown();
System.out.println("多任务计算后的总结果是:" + totalResult);
}
-
FutureTask可用于异步获取执行结果或取消执行任务的场景。 -
经过传入Runnable或者Callable的任务给FutureTask, -
直接调用其run方法或者放入线程池执行, -
以后能够在外部经过FutureTask的get方法异步获取执行结果,所以, -
FutureTask很是适合用于耗时的计算,主线程能够在完成本身的任务后, -
再去获取结果。另外,FutureTask还能够确保即便调用了屡次run方法, -
它都只会执行一次Runnable或者Callable任务,或者经过cancel取消FutureTask的执行等
一般两种常见的使用场景,以上是第一种,多个并行任务同时计算,统计汇总结果
以下是第二种,用于高并发下保证只运行一次的情况
保证在高并发时,只创建一次连接。为了方便测试,只是做了模拟
public static void main(String[] args) {
/**
* 2、保证高并发情况下,某些任务只执行一次
* 传统的我们可以通过加锁的方式进行,这里我们采用futureTask
*/
FuntureTaskDemo funtureTaskDemo = new FuntureTaskDemo();
for(int i=0;i<10;i++){
new Thread(()->{
try {
System.out.println(Thread.currentThread().getName()+"t"+funtureTaskDemo.getConnection("mm"));
} catch (Exception e) {
e.printStackTrace();
}
},String.valueOf(i)).start();
}
}
class InnerConnection{
public InnerConnection(String url) {
this.url = url;
}
private String url;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
class FuntureTaskDemo{
private ConcurrentHashMap<String, FutureTask<InnerConnection>> connectionPool = new ConcurrentHashMap<String, FutureTask<InnerConnection>>();
public InnerConnection getConnection(String key) throws Exception {
FutureTask<InnerConnection> connectionTask = connectionPool.get(key);
if (connectionTask != null) {
return connectionTask.get();
} else {
Callable<InnerConnection> callable = new Callable<InnerConnection>() {
@Override
public InnerConnection call() throws Exception {
// TODO Auto-generated method stub
return createConnection();
}
};
FutureTask<InnerConnection> newTask = new FutureTask<InnerConnection>(callable);
connectionTask = connectionPool.putIfAbsent(key, newTask);
if (connectionTask == null) {
connectionTask = newTask;
connectionTask.run();
}
return connectionTask.get();
}
}
//建立Connection
private InnerConnection createConnection() {
System.out.println("阻塞中************");
try {TimeUnit.SECONDS.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}
System.out.println("阻塞结束************");
return new InnerConnection("9999");
}
}
原文始发于微信公众号(云户):JUC–线程创建
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/35338.html