接口定义

#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. L1-054 福到了

    “福”字倒着贴,寓意“福到”.不论到底算不算民俗,本题且请你编写程序,把各种汉字倒过来输出.这里要处理的每个汉字是由一个 N × N 的网格组成的,网格中的元素或者为字符 @ 或者为空格.而倒过来的汉 ...

  2. Android开发 --代码布局

    Android开发 --代码布局 在线性布局LinearLayout里加入view比较简单,因为属性比较少,布局简单 示例,加入一个TextView LinearLayout layout = (Li ...

  3. org.quartz-scheduler 动态添加自动任务

    1.添加pom.xml <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId> ...

  4. python列表的11种方法

    python列表的11种方法2017年11月24日 03:26:43 Milton-Long 阅读数:254版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.n ...

  5. foreman源NO_PUBKEY 6F8600B9563278F6

    /etc/apt/sources.list.d/foreman.list # foreman deb http://deb.theforeman.org xenial stable 一条命令解决 ap ...

  6. HDU 1004 Let the Balloon Rise(map应用)

    Problem Description Contest time again! How excited it is to see balloons floating around. But to te ...

  7. 1.带宽&吞吐量

    1.带宽         网络带宽是指在一个固定的时间内(1秒),能通过的最大位数据.就好象高速公路的车道一样,带宽越大,好比车道越多 带宽是一个非常有用的概念,在网络通信中的地位十分重要.带宽的实际 ...

  8. 【Python】etree方法生成,解析xml

    #练习:另一种遍历xml文件的方式etree,xpathimport systry: import xml.etree.cElementTree as ET #前面带c的都是比较快的,效率高且不占内存 ...

  9. pdb的数量限制

    Decide How to Configure the CDB --搜索文档 Prepare to create the CDB by research and careful planning. T ...

  10. Python中的print、input函数以及Python中交换两个变量解析

    一.Python中的值交换操作 首先明确一点点,Python中的一切都是面向对象的,可以理解为Python的中一切都是对象. 我们知道Java也是面向对象的语言,但是在Java中定义一个值变量如下: ...