Callable 和 Runnable 的 区别(简单分析)

60 篇文章 8 订阅
42 篇文章 2 订阅

 

1、区别

不同点Callable Runnable
方法 V call()  throws Exceptionrun()
返回值 V call()  有返回值void run()  没有返回值
异常call() 可以抛出受检查的异常run() 不能抛出异常
启动

1、使Thread 来包装,使用start() 启动

2、提交给 线程池 ExecuteService.submit() 启动

1、使Thread 来包装,使用start() 启动

2、提交给 线程池 ExecuteService.submit() 和execute() 启动

 

注意:execute() 只接收Runnable实现类,且没有返回值

 


2、Callable示例如下: 

class CallableImpl implements Callable {
	private int age;

	public CallableImpl(int age) {
		this.age = age;
	}

	// 具体逻辑在这里实现,并有一个返回值
	public Object call() throws Exception {
		Thread.currentThread().sleep(new Random().nextInt(1000));
		String ss="";
		if (age < 0) {
			ss="age = " + age + ", 输入年龄有误";
		} else if (age < 20) {
			ss="age = " + age + ", 你好,年轻人";
		} else if (age < 40) {
			ss= "age = " + age + ", 你好,中年人";
		} else {
			ss= "age = " + age + ", 你好,老年人";
		}
		System.out.println(ss);
		return ss;
	}
}

public class CallableTest {

	public static void main(String[] args) throws InterruptedException, ExecutionException {

		// 建立一个线程池
		ExecutorService exc = Executors.newFixedThreadPool(3);
		// 存放返回的结果
		List<Future<String>> futures = new ArrayList<Future<String>>();

		for (int i = -10; i < 50; i += 3) {
			CallableImpl call = new CallableImpl(i);
			// 执行callable的call方法,并有返回值
			Future<String> future = exc.submit(call);
			futures.add(future);

		}
		System.out.println("等待结果:");
		for (Future<String> future : futures) {  
            // 这里调用get()方法会阻塞当前线程,直到得到返回结果  
            System.out.println("----------- "+future.get());  
            // if (future.isDone()) {  
            // System.out.println(future.get());  
            // } else {  
            // System.out.println("Future result is not yet complete");  
            // }  
        }
		System.out.println("结束...");
		//Thread.currentThread().sleep(1000*30);
		exc.shutdown();
	}
}


结果:

等待结果:
age = -10, 输入年龄有误
----------- age = -10, 输入年龄有误
age = -4, 输入年龄有误
age = -1, 输入年龄有误
age = 2, 你好,年轻人
age = -7, 输入年龄有误
----------- age = -7, 输入年龄有误
----------- age = -4, 输入年龄有误
----------- age = -1, 输入年龄有误
----------- age = 2, 你好,年轻人
age = 11, 你好,年轻人
age = 5, 你好,年轻人
----------- age = 5, 你好,年轻人
age = 8, 你好,年轻人
----------- age = 8, 你好,年轻人
----------- age = 11, 你好,年轻人
age = 17, 你好,年轻人
age = 14, 你好,年轻人
----------- age = 14, 你好,年轻人
----------- age = 17, 你好,年轻人
age = 26, 你好,中年人
age = 23, 你好,中年人
age = 20, 你好,中年人
----------- age = 20, 你好,中年人
----------- age = 23, 你好,中年人
----------- age = 26, 你好,中年人
age = 35, 你好,中年人
age = 32, 你好,中年人
age = 41, 你好,老年人
age = 29, 你好,中年人
----------- age = 29, 你好,中年人
----------- age = 32, 你好,中年人
----------- age = 35, 你好,中年人
age = 38, 你好,中年人
----------- age = 38, 你好,中年人
----------- age = 41, 你好,老年人
age = 44, 你好,老年人
----------- age = 44, 你好,老年人
age = 47, 你好,老年人
----------- age = 47, 你好,老年人
结束...

 

3、Runnable示例:

public class LiftOff implements Runnable {

	protected int countDown = 10;
	private static int taskCount = 0;
	private final int id = taskCount++;

	public LiftOff() {

	}

	public LiftOff(int countDown) {
		this.countDown = countDown;
	}

	public String status() {
		return "#" + id + "(" + (countDown > 0 ? countDown : "LiftOff! ") + ")";
	}

	@Override
	public void run() {
		while (countDown-- > 0) {
			System.out.print(status());
			Thread.yield();
		}
		System.out.println();
	}

	public static void main(String[] args) {
		ExecutorService exec = Executors.newFixedThreadPool(1);
		for (int i = 0; i < 5; i++) {
			exec.execute(new LiftOff());
		}
		exec.shutdown();
	}
}

 

 

 

注意ExecutorService 在Callable中使用的是submit(), 在Runnable中使用的是 execute()。
 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值