当前位置: 首页 > >

libevent c++高并发网络编程_【多线程高并发编程】Callable源码分析

发布时间:


程序猿学社的GitHub,欢迎
Star
https://
github.com/ITfqyd/cxyxs







通过这种方式,我们是不是实现了,获取线程的结果。现在我们总结一下通过runnable方式,是如何实现获取多线程的返回接口的。定义一个类实现Runnable接口 定义一个成员变量,用来接收run方法运行后,我们需要的结果。调用时,实例化该类,作为形参传入Thread中,调用start方法启动线程调用线程的join方法 ,等待线程执行完毕,这样我们才能取到线程执行完后的结果5,不然就是0.
1.2 Callable的今生
通过FutureTask+Thread调用

package com.cxyxs.thread.three;

import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

/**
* Description:转发请注明来源 程序猿学社 - https://ithub.blog.csdn.net/
* Author: 程序猿学社
* Date: 2020/2/19 0:12
* Modified By:
*/
public class MyThreadCallable {
public static void main(String[] args) throws Exception{
//第一步
Callable callable = new Callable() {
@Override
public Integer call() throws Exception {
int count=0;
for (int i = 0; i < 5; i++) {
Thread.sleep(1200);
count++;
}
return count;
}
};

FutureTask task = new FutureTask<>(callable);

Thread thread = new Thread(task);
thread.start();

Integer result = task.get();
System.out.println("获取多线程的值:"+result);
}
}


为了偷懒,这里第一步简写了,一般都是类实现Callable接口,重写call,我这里使用简写的方法实现。实例化一个FutureTask,把实现Callable的类,作为构造方法的形参传入进去。实例化一个线程,把FutureTask这个对象,作为构造方法的形参传入。调用FutureTask对象的get方法。就可以获取值。
ExecutorService+Future调用实现

public void two() throws Exception{
Callable callable = new Callable() {
@Override
public Integer call() throws Exception {
int count=0;
for (int i = 0; i < 5; i++) {
Thread.sleep(1200);
count++;
}
return count;
}
};

ExecutorService e= Executors.newFixedThreadPool(10);
Future f1=e.submit(callable);
Integer result = f1.get();
System.out.println("获取多线程的值:"+result);
}


建议,使用这种方式,通过线程池管理多线程。引出一个问题,为什么要使用线程池?
public FutureTask(Callable callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
}


如果没有传Callable就抛出NullPointerException.我们发现这里有一个变量state的值为NEW



/*
* Possible state transitions:
* NEW -> COMPLETING -> NORMAL
* NEW -> COMPLETING -> EXCEPTIONAL
* NEW -> CANCELLED
* NEW -> INTERRUPTING -> INTERRUPTED
*/
private volatile int state;
private static final int NEW = 0;
private static final int COMPLETING = 1;
private static final int NORMAL = 2;
private static final int EXCEPTIONAL = 3;
private static final int CANCELLED = 4;
private static final int INTERRUPTING = 5;
private static final int INTERRUPTED = 6;


NEW(初始化)COMPLETING(运行中)NORMAL(完成状态)EXCEPTIONAL(任务因异常而结束)CANCELLED(还未运行就调用cancel(true)方法取消)INTERRUPTING(正在运行中就调用cancel(true)方法被取消)INTERRUPTED(被取消状态,由INTERRUPTING转换成INTERRUPTED)
public V get() throws InterruptedException, ExecutionException {
int s = state;
if (s <= COMPLETING)
s = awaitDone(false, 0L);
return report(s);
}


COMPLETING标识运行中,判断这个任务是否已经在运行中,也就是已调用run方法。说明任务还未完成,我们需要等待,所以这里调用了awaitDone方法。


返回结果是调用的report方法

private V report(int s) throws ExecutionException {
Object x = outcome;
if (s == NORMAL)
return (V)x;
if (s >= CANCELLED)
throw new CancellationException();
throw new ExecutionException((Throwable)x);
}


如果状态为已完成(NORMAL),直接返回运行结果。


关注 【 @程序猿学社 】回复关键字,查看更多干货。







相关资源:Libevent C++ 高并发网络编程



友情链接: