接口定义

#Callable接口

public interface Callable<V> {
V call() throws Exception;
}

#Runnable接口

public interface Runnable {
public abstract void run();
}

相同点

都是接口

都可以编写多线程程序

都采用Thread.start()启动线程

不同点

Runnable没有返回值;Callable可以返回执行结果,是个泛型,和Future、FutureTask配合可以用来获取异步执行的结果

Callable接口的call()方法允许抛出异常;Runnable的run()方法异常只能在内部消化,不能往上继续抛

:Callalble接口支持返回执行结果,需要调用FutureTask.get()得到,此方法会阻塞主进程的继续往下执行,如果不调用不会阻塞。

示例

#Callable-1

import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask; public class CallableAndFuture {
public static void main(String[] args) {
Callable<Integer> callable = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
Thread.sleep(6000);
return new Random().nextInt();
}
};
FutureTask<Integer> future = new FutureTask<>(callable);
new Thread(future).start();
try {
Thread.sleep(1000);
System.out.println("hello begin");
System.out.println(future.isDone());
System.out.println(future.get());
System.out.println(future.isDone());
System.out.println("hello end");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}

结果

hello begin
false
1664014921
true
hello end

#Callable-2

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask; public class CallableThreadTest implements Callable<Integer> {
public static void main(String[] args) throws ExecutionException, InterruptedException {
CallableThreadTest ctt = new CallableThreadTest();
FutureTask<Integer> ft = new FutureTask<>(ctt);
new Thread(ft, "有返回值的线程").start();
System.out.println("子线程的返回值" + ft.get());
} @Override
public Integer call() {
int i;
for (i = 0; i < 10; i += 2) {
System.out.println(Thread.currentThread().getName() + " " + i);
}
return i;
}
}

结果

有返回值的线程 0
有返回值的线程 2
有返回值的线程 4
有返回值的线程 6
有返回值的线程 8
子线程的返回值10

优势

多线程返回执行结果是很有用的一个特性,因为多线程相比单线程更难、更复杂的一个重要原因就是因为多线程充满着未知性,某条线程是否执行了?某条线程执行了多久?某条线程执行的时候我们期望的数据是否已经赋值完毕?无法得知,我们能做的只是等待这条多线程的任务执行完毕而已。而Callable+Future/FutureTask却可以获取多线程运行的结果,可以在等待时间太长没获取到需要的数据的情况下取消该线程的任务,真的是非常有用。

public class CallableAndFuture {
public static void main(String[] args) {
Callable<Integer> callable = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
Thread.sleep(6000);
return new Random().nextInt();
}
};
FutureTask<Integer> future = new FutureTask<>(callable);
new Thread(future).start();
try {
Thread.sleep(1000);
System.out.println("hello begin");
System.out.println(future.isDone());
// future.cancel(false);
if (!future.isCancelled()) {
System.out.println(future.get());
System.out.println(future.isDone());
System.out.println("hello end");
} else {
System.out.println("cancel~");
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}

Java Runnable与Callable区别的更多相关文章

  1. Java多线程Runnable与Callable区别与拓展

    我们先来分别看一下这两个接口 Runnable: // // Source code recreated from a .class file by IntelliJ IDEA // (powered ...

  2. Runnable与Callable区别

    相同点: 两者都是接口:(废话) 两者都可用来编写多线程程序: 两者都需要调用Thread.start()启动线程: 不同点: 两者最大的不同点是:实现Callable接口的任务线程能返回执行结果:而 ...

  3. java Runnable、Callable、FutureTask 和线程池

    一:Runnable.Callable.FutureTask简介 (1)Runnable:其中的run()方法没有返回值. ①.Runnable对象可以直接扔给Thread创建线程实例,并且创建的线程 ...

  4. Java Runnable和Thread区别

    Thread是多个线程分别完成自己的任务,Runnable是多个线程共同完成1个任务.在实际开发中,一个多线程的操作很少使用Thread类,而是通过Runnable接口完成,好处有: 1. 避免点继承 ...

  5. java 并发包runnable 与 callable

    1.runnable 与 callable区别 2.避免callable执行完任务,获取返回结果时,阻塞其他子线程 下面固定线程池,设置4个,表明同时只有4个线程在执行任务,当某个线程执行完一个任务, ...

  6. Android进阶——多线程系列之Thread、Runnable、Callable、Future、FutureTask

    多线程一直是初学者最抵触的东西,如果你想进阶的话,那必须闯过这道难关,特别是多线程中Thread.Runnable.Callable.Future.FutureTask这几个类往往是初学者容易搞混的. ...

  7. java多线程—Runnable、Thread、Callable区别

    多线程编程优点 进程之间不能共享内存,但线程之间共享内存非常容易. 系统创建线程所分配的资源相对创建进程而言,代价非常小. Java中实现多线程有3种方法: 继承Thread类 实现Runnable接 ...

  8. Java线程—-Runnable和Callable的区别和联系

    Java 提供了三种创建线程的方法 1.继承Thread接口 public class Thread2Thread { public static void main(String[] args) { ...

  9. Java中的Runnable、Callable、Future、FutureTask的区别与示例

    Java中存在Runnable.Callable.Future.FutureTask这几个与线程相关的类或者接口,在Java中也是比较重要的几个概念,我们通过下面的简单示例来了解一下它们的作用于区别. ...

随机推荐

  1. 阶段01Java基础day13常见对象02

    13.01_常见对象(StringBuffer类的概述) A:StringBuffer类概述 通过JDK提供的API,查看StringBuffer类的说明 线程安全的可变字符序列 B:简述安全问题 线 ...

  2. 特殊权限stick_bit

    stick_bit 防删除位:文件是否可以被某用户删除,主要取决于该文件所在的目录是否对该用户具有写权限.如果没有写权限,则这个目录下的所有文件都不能删除,同时也不能添加新的文件.如果希望用户能够添加 ...

  3. <Using parquet with impala>

    Operations upon Impala Create table stored as parquet like parquet '/user/etl/datafile1' stored as p ...

  4. 【python】pandas display选项

    import pandas as pd 1.pd.set_option('expand_frame_repr', False) True就是可以换行显示.设置成False的时候不允许换行 2.pd.s ...

  5. shell脚本实例-判断主机存活 以及企业备份方案

    1.上次写了一个脚本我那次考虑不是很周全,这次我将脚本改动了一下,这次是判断三次, 希望关注我的人可以经常交流哈.下面我写上代码. #!/usr/bin/bash while read ip do f ...

  6. 句柄线程做参数和PostMessage的用法

    当我们启动一个线程,并且要给线程函数传递的参数是窗口句柄时,我们应该这样做: HWND hHwnd = GetSafeHwnd(); HANDLE hThread; DWORd dwThreadId; ...

  7. Beta阶段冲刺---Day3

    一.Daily Scrum Meeting照片 二.今天冲刺情况反馈 昨天已完成的工作: (1)数字以扑克牌的形式给出 (2)答案的乘除符号与游戏中的符号保持一致. 今天计划完成的工作 (1)闯关模式 ...

  8. 使用scrapy ImagesPipeline爬取图片资源

    这是一个使用scrapy的ImagesPipeline爬取下载图片的示例,生成的图片保存在爬虫的full文件夹里. scrapy startproject DoubanImgs cd DoubanIm ...

  9. POJ 3461 Oulipo(KMP裸题)

    Description The French author Georges Perec (1936–1982) once wrote a book, La disparition, without t ...

  10. google和baidu搜索命令

    在google里面搜索一点儿老外的资料的时候发现搜不到我想要的东西,以前貌似见过一个搜索命令的但是一时想不起来了,所以就去搜索了一下搜索命令,常用的在这里全部列举出来: google:绿色的较为常用的 ...