java 多线程Callable和Runable执行顺序问题详解

简介:

毫无疑问 Runnable会进行异步执行,此处不多数,主要说明Callable的使用,看实例:

1、

public class ThreadTest {

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

        ExecutorService executor = Executors.newFixedThreadPool(4);

        MyTread m1 = new MyTread();

        Future f = executor.submit(m1);

        // System.out.println(f.get());

        executor.shutdown();

        System.out.println("主线程执行完了");

    }

 

}

 

class MyTread implements Callable<String> {

    @Override

    public String call() {

        try {

            System.out.println("线程调度:" + Thread.currentThread());

            TimeUnit.SECONDS.sleep(3);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

        return "123";

    }

}

此程序虽然获取了call方法的返回值,但是没有做处理,所以主线程main和m1同时执行,执行结果如下:

主线程执行完了

线程调度:Thread[pool-1-thread-1,5,main]

 

2、

public class ThreadTest {

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

        ExecutorService executor = Executors.newFixedThreadPool(4);

        MyTread m1 = new MyTread();

        Future f = executor.submit(m1);

        System.out.println(f.get()); // 进行了输出

        executor.shutdown();

        System.out.println("主线程执行完了");

    }

 

}

 

class MyTread implements Callable<String> {

    @Override

    public String call() {

        try {

            System.out.println("线程调度:" + Thread.currentThread());

            TimeUnit.SECONDS.sleep(3);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

        return "123";

    }

}

 

在2中,对m1中call方法的返回值在main中进行了处理(输出),所以在此种情况下,main需要等待m1执行完,再继续执行,执行结果如下

线程调度:Thread[pool-1-thread-1,5,main]

123

主线程执行完了

 

3、再看当主线程中同时启动两个由Callable生成的线程时

public class ThreadTest {

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

        ExecutorService executor = Executors.newFixedThreadPool(4);

        MyTread m1 = new MyTread();

        MyTread2 m2 = new MyTread2();

        Long time1 = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());

        Future f = executor.submit(m1);

        Future f2 = executor.submit(m2);

        System.out.println(f.get()); // 进行了输出m1

        System.out.println(f2.get()); // 进行了输出m2

        executor.shutdown();

        System.out.println("主线程执行完了");

        Long time2 = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());

        System.out.println("主线程等待了" + (time2 - time1) + "秒");

    }

 

}

 

class MyTread implements Callable<String> {

    @Override

    public String call() {

        try {

            System.out.println("线程调度:" + Thread.currentThread());

            TimeUnit.SECONDS.sleep(3);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

        return "123";

    }

}

 

class MyTread2 implements Callable<String> {

    @Override

    public String call() {

        try {

            System.out.println("线程调度2:" + Thread.currentThread());

            TimeUnit.SECONDS.sleep(3);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

        return "abc";

    }

}

当不对m1和m2做输出时,main和m1、m2并发执行,当对m1和m2中任意一个的返回值进行处理的时候,main需要等待,但是m1和m2之前仍然是并发执行,执行结果如下:

线程调度2:Thread[pool-1-thread-2,5,main]

线程调度:Thread[pool-1-thread-1,5,main]

123

abc

主线程执行完了

主线程等待了3秒


特别说明:尊重作者的劳动成果,转载请注明出处哦~~~http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt125
相关文章
|
3天前
|
缓存 安全 Java
7张图带你轻松理解Java 线程安全,java缓存机制面试
7张图带你轻松理解Java 线程安全,java缓存机制面试
|
1天前
|
Java
深入理解Java并发编程:线程池的应用与优化
【5月更文挑战第18天】本文将深入探讨Java并发编程中的重要概念——线程池。我们将了解线程池的基本概念,应用场景,以及如何优化线程池的性能。通过实例分析,我们将看到线程池如何提高系统性能,减少资源消耗,并提高系统的响应速度。
11 5
|
1天前
|
消息中间件 安全 Java
理解Java中的多线程编程
【5月更文挑战第18天】本文介绍了Java中的多线程编程,包括线程和多线程的基本概念。Java通过继承Thread类或实现Runnable接口来创建线程,此外还支持使用线程池(如ExecutorService和Executors)进行更高效的管理。多线程编程需要注意线程安全、性能优化和线程间通信,以避免数据竞争、死锁等问题,并确保程序高效运行。
|
1天前
|
存储 Java
【Java】实现一个简单的线程池
,如果被消耗完了就说明在规定时间内获取不到任务,直接return结束线程。
8 0
|
1天前
|
安全 Java 容器
深入理解Java并发编程:线程安全与性能优化
【5月更文挑战第18天】随着多核处理器的普及,并发编程变得越来越重要。Java提供了丰富的并发编程工具,如synchronized关键字、显式锁Lock、原子类、并发容器等。本文将深入探讨Java并发编程的核心概念,包括线程安全、死锁、资源竞争等,并分享一些性能优化的技巧。
|
1天前
|
安全 Java 开发者
Java中的多线程编程:理解与实践
【5月更文挑战第18天】在现代软件开发中,多线程编程是提高程序性能和响应速度的重要手段。Java作为一种广泛使用的编程语言,其内置的多线程支持使得开发者能够轻松地实现并行处理。本文将深入探讨Java多线程的基本概念、实现方式以及常见的并发问题,并通过实例代码演示如何高效地使用多线程技术。通过阅读本文,读者将对Java多线程编程有一个全面的认识,并能够在实际开发中灵活运用。
|
1天前
|
算法 Java 程序员
Java中的线程同步与并发控制
【5月更文挑战第18天】随着计算机技术的不断发展,多核处理器的普及使得多线程编程成为提高程序性能的关键。在Java中,线程是实现并发的一种重要手段。然而,线程的并发执行可能导致数据不一致、死锁等问题。本文将深入探讨Java中线程同步的方法和技巧,以及如何避免常见的并发问题,从而提高程序的性能和稳定性。
|
2天前
|
存储 安全 Java
Java多线程基础知识总结,36岁老码农现身说法
Java多线程基础知识总结,36岁老码农现身说法
|
2天前
|
Java 测试技术
Java多线程的一些基本例子
【5月更文挑战第17天】Java多线程允许并发执行任务。示例1展示创建并启动两个`MyThread`对象,各自独立打印&quot;Hello World&quot;。示例2的`CounterExample`中,两个线程(IncrementThread和DecrementThread)同步地增加和减少共享计数器,确保最终计数为零。这些例子展示了Java线程的基本用法,包括线程同步,还有如Executor框架和线程池等更复杂的用例。
9 0
|
3天前
|
Java
阅读《代码整洁之道》总结(1),java多线程面试
阅读《代码整洁之道》总结(1),java多线程面试