【线程】Java让线程执行也具有返回值

Thread线程的run方法是没有返回值的。

 /**
     * If this thread was constructed using a separate
     * <code>Runnable</code> run object, then that
     * <code>Runnable</code> object's <code>run</code> method is called;
     * otherwise, this method does nothing and returns.
     * <p>
     * Subclasses of <code>Thread</code> should override this method.
     *
     * @see     #start()
     * @see     #stop()
     * @see     #Thread(ThreadGroup, Runnable, String)
     */
    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }

Thread的成员变量是一个线程链接类:实现了Runnable接口的对象,这个对象的run方法也是没有返回值的。

@FunctionalInterface
public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

传统的使用new Thread(Runnable r).start()的启动Runnable的方式直接调用的是Runnable的run方法,这种是没有返回值的。

如何让线程返回执行结果呢,比如返回一个布尔值true

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

有两种方法。

第一种方法:使用线程池来提交调用Runnable。

    @Test
    public void test() {
        ExecutorService executorService = Executors.newCachedThreadPool();
        Future demoFuture2 = executorService.submit(new DemoRunnable(1),"123456");
        try {
            System.out.println(demoFuture2.get());
        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }

Executors.newCachedThreadPool()这里返回了一个线程池,executorService.submit调用了一个Runnable并且返回一个异步计算结果Future,参数“123456”是Future执行get方法(阻塞了当前线程)得到的返回值。如果我们不传入参数“123456”,即

        Future demoFuture2 = executorService.submit(new DemoRunnable(1));

返回值是null,因为默认是没有返回值的。

这种方法非常只能勉强返回一个固定的值,不是我们预期的功能。难道Java这么弱鸡真的没有其他办法了吗?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

有的。

第二种方法:使用Callable来代替Runnable。

@FunctionalInterface
public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}
    @Test
    public void test() {
        ExecutorService executorService = Executors.newCachedThreadPool();
        Future<Boolean> demoFuture = executorService.submit(new DemoCallable(1));
        try {
            System.out.println(demoFuture.get());
        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }


// 一个Callable的Demo
class DemoCallable implements Callable<Boolean> {
    private Integer id;
    public DemoCallable(int id) {
        Thread.currentThread().setName(Thread.currentThread().getName() + id);
        this.id = id;
    }
    @Override
    public Boolean call() throws Exception {
        for (int i = 0; i < 30 ; i++) {
            Thread.sleep(1000);
            System.out.println(i + ":" + Thread.currentThread().getName());
        }
        return true;
    }
}

单元测试运行结果:

可以看到,第二种方法更加灵活,而且支持抛出异常。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
java实现线程返回值方法有多种。其中一种方法是通过继承Thread类或者实现Runnable接口,在子线程中设置共享变量来获取返回值。这种方法的缺点是不能精确判断子线程是否执行完成。另一种方法是通过实现Callable接口,使用FutureTask启动子线程,然后使用FutureTask的get()方法获取返回值。这种方法可以精确地获取返回值。 以下是两种方法的示例代码: 方法一,通过设置共享变量获取返回值: ```java public class TestThread extends Thread { public String value = null; @Override public void run() { System.out.println("TestThread start...."); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("TestThread end"); value = "TestThread"; } } public class Main { public static void main(String[] args) throws InterruptedException { TestThread thread = new TestThread(); thread.start(); while (thread.value == null) { Thread.sleep(100); } System.out.println(thread.value); } } ``` 方法二,使用Callable和FutureTask获取返回值: ```java import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; public class TestCallable implements Callable<String> { @Override public String call() throws Exception { System.out.println("TestCallable start...."); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("TestCallable end"); return "TestCallable"; } } public class Main { public static void main(String[] args) throws ExecutionException, InterruptedException { FutureTask<String> futureTask = new FutureTask<>(new TestCallable()); Thread thread = new Thread(futureTask); thread.start(); String value = futureTask.get(); System.out.println(value); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值