Java线程的使用方式最基础的来说只有两种:实现Runnable和Callable接口,继承Thread类实际也是间接实现了Runnable接口。两者的区别的是Runnable没有返回值,而Callable有返回值。
1.实现Runnable接口的线程:
class RunnableThread implements Runnable{
@Override
public void run() {
System.out.println("我是Runnable方式实现的线程,我没有返回值");
}
}
2.实现Callable接口的线程
class CallableThread<String> implements Callable<Object>{
@Override
public Object call() throws Exception {
return "我是Callable方式实现的线程,我就是返回值";
}
}
3.继承Thread类的线程
因为Java是单继承的,所以慎重使用。
class ExtendsThread extends Thread{
public void run() {
System.out.println("我是继承Thread方式实现的线程");
}
}
Executor框架-线程池
任务是一组逻辑单元,而线程则是使任务异步执行的机制。Java类库中,任务执行的抽象不是Thread,而是Executor。
void t0() throws InterruptedException, ExecutionException{
Callable<Object> c = new TestCallable("参数");
Runnable r = new TestRunnable();
final ExecutorService pool = Executors.newFixedThreadPool(2);
pool.execute(r);
FutureTask<Object> task = new FutureTask<Object>(c);
pool.submit(task);
System.out.println(task.get());
pool.shutdown();
}
/**
* Callable与FutureTask
*/
private List<FutureTask<Object>> tasks = new ArrayList<FutureTask<Object>>();
void t1() throws InterruptedException, ExecutionException{
final ExecutorService pool = Executors.newFixedThreadPool(2);
Callable<Object> c1 = new TestCallable("参数1...");
FutureTask<Object> task1 = new FutureTask<Object>(c1);
tasks.add(task1);
if (!pool.isShutdown()) {//ExecutorService具有生命周期
pool.submit(task1);
}
Callable<Object> c2 = new TestCallable("参数2...");
FutureTask<Object> task2 = new FutureTask<Object>(c2);
tasks.add(task2);
if (!pool.isShutdown()) {
pool.submit(task2);
}
String res = "";
for(int i=0;i<tasks.size();i++){
res+=tasks.get(i).get();
}
System.out.println("并行运算的结果:"+res);
pool.shutdown();
}
/**
* Callable与ExecutorCompletionService
* 调用CompletionService的take方法是,会返回按完成顺序放回任务的结果,
CompletionService内部维护了一个阻塞队列BlockingQueue
*/
private CompletionService<Object> completionService;
void t2() throws InterruptedException, ExecutionException{
final ExecutorService pool = Executors.newFixedThreadPool(2);
completionService = new ExecutorCompletionService<Object>(pool);
Callable<Object> c1 = new TestCallable("参数3...");
if (!pool.isShutdown()) {//ExecutorService具有生命周期
completionService.submit(c1);
}
Callable<Object> c2 = new TestCallable("参数4...");
if (!pool.isShutdown()) {
completionService.submit(c2);
}
String res = "";
for(int i=0;i<2;i++){
res+=completionService.take().get();
}
System.out.println("并行运算的结果:"+res);
pool.shutdown();
}
/**
* 设置限时
* @throws InterruptedException
* @throws ExecutionException
* @throws TimeoutException
*/
void t3() throws InterruptedException, ExecutionException{
Callable<Object> c = new TestTimeoutCallable("参数...");
final ExecutorService pool = Executors.newFixedThreadPool(2);
FutureTask<Object> task = new FutureTask<Object>(c);
pool.submit(task);
try {
System.out.println(task.get(500,TimeUnit.MILLISECONDS));
//设置现实,超过限时将不执行,并抛出异常,参数换为500和5000,效果不同
} catch (TimeoutException e) {
task.cancel(true);
e.printStackTrace();
}
pool.shutdown();
}
/**
* 通过调用设置限时
* @throws InterruptedException
* @throws ExecutionException
* @throws TimeoutException
*/
private List<TestTimeoutCallable> ttcl = new ArrayList<TestTimeoutCallable>();
void t4(){
Callable<Object> c = new TestTimeoutCallable("参数...");
final ExecutorService pool = Executors.newFixedThreadPool(2);
ttcl.add((TestTimeoutCallable) c);
List<Future<Object>> futures;
try {
futures = pool.invokeAll(ttcl,5000,TimeUnit.MILLISECONDS);
//参数换为500和5000,效果不同
for(Future<Object> f:futures){
try {
System.out.println(f.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}finally{
pool.shutdown();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
pool.shutdown();
}
pool.shutdown();
}
static class TestCallable implements Callable<Object>{
private String param;
TestCallable(String param) {
this.param = param;
}
@Override
public Object call() throws Exception {
System.out.println("callable线程..."+param);
Object p = new String(param);
return p;
}
}
static class TestTimeoutCallable implements Callable<Object>{
private String param;
TestTimeoutCallable(String param) {
this.param = param;
}
@Override
public Object call() throws Exception {
System.out.println("callable线程..."+param);
Object p = new String(param);
Thread.sleep(2000);//模拟业务计算,耗时2000毫秒
return p;
}
}
static class TestRunnable implements Runnable{
@Override
public void run() {
System.out.println("runnable线程...");
}
}