精华内容
下载资源
问答
  • 1.继承Thread,并重写run()方法,重写run方法,该方法是线程执行体public class MyThread extends Thread{int i=0;@Overridepublic void run() {for (; i < 100; i++) {System.out.println(getName() + ":" + i);}...

    1.继承Thread,并重写run()方法,重写run方法,该方法是线程执行体

    public class MyThread extends Thread{

    int i=0;

    @Override

    public void run() {

    for (; i < 100; i++) {

    System.out.println(getName() + ":" + i);

    }

    }

    public static void main(String[] args) {

    for (int i = 0; i < 100; i++) {

    System.out.println(Thread.currentThread().getName() + ":" + i);

    if (i == 20) {

    new MyThread().start();

    new MyThread().start();

    }

    }

    }

    }

    2.通过Runable去创建线程,也是重写run方法,该方法是线程执行体

    public class MyRunnable implements Runnable {

    private int i=0;

    @Override

    /**

    * 重写run方法,该方法同样是该线程的线程执行体

    */

    public void run() {

    for (; i < 100; i++) {

    System.out.println(Thread.currentThread().getName() + ":" + i);

    try {

    Thread.sleep(1000);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    }

    public static void main(String[] args) {

    for (int i = 0; i < 100; i++) {

    System.out.println(Thread.currentThread().getName() + ":" + i);

    if (i == 20) {

    MyRunnable runnable = new MyRunnable();

    //该Thread对象才是真正的线程对象.

    new Thread(runnable, "新线程-1").start();

    new Thread(runnable, "新线程-2").start();

    }

    }

    }

    }

    执行结果部分结果:

    新线程-2:80

    新线程-1:81

    新线程-2:82

    新线程-1:83

    新线程-2:84

    新线程-1:85

    新线程-2:86

    新线程-1:87

    新线程-2:88

    新线程-1:89

    新线程-2:90

    新线程-1:91

    新线程-2:92

    新线程-1:93

    新线程-2:94

    新线程-1:95

    新线程-2:96

    新线程-1:97

    新线程-2:98

    新线程-1:99

    可以看出线程1和线程2共享了MyRunnable实例对象的i。

    3.通过Callable和Future创建线程,通过继承Thread和Runable创建的线程,在线程执行完成之后无法获取执行结果。

    如果需要获取线程执行结果,就需要通过共享变量或者是线程通信的方法来达到效果,使用起来比较麻烦。

    通过重写Callable接口中的call()方法,该方法是有返回值的,Future可以得到线程执行完成之后的结果值。

    public class MyCallable implements Callable {

    @Override

    /**

    * 重写call方法,即为线程的执行体

    */

    public Integer call() throws Exception {

    int i = 0;

    for (; i < 100; i++) {

    System.out.println(Thread.currentThread().getName() + ":" + i);

    }

    return i;

    }

    public static void main(String[] args) {

    //获取实习callable接口的类的实例

    MyCallable callable = new MyCallable();

    //使用FutureTask类来包装Callable对象,

    // 该FutureTask对象封装了该Callable对象的call()方法的返回值。

    FutureTask task = new FutureTask<>(callable);

    for (int i = 0; i < 100; i++) {

    System.out.println(Thread.currentThread().getName() + ":" + i);

    if (i == 20) {

    new Thread(task, "有返回值的线程").start();

    try {

    System.out.println("子线程的返回值:" + task.get());

    } catch (InterruptedException e) {

    e.printStackTrace();

    } catch (ExecutionException e) {

    e.printStackTrace();

    }

    }

    }

    }

    }

    三种创建线程方式比较:

    1)实现Runnable和Callable接口,还可以继承其他类,继承了Thread类就不能集成其他类型。

    2)继承Thread类编程比较简单,如果要访问当前线程,可以直接使用this指针得到,如果是实现Runnable和Callable接口,要使用Thread.currentThread()方法得到当前线程

    3)实现Runnable和Callable接口时,多个线程可以共享一个实现Runnable和Callable接口类的实例变量,但是如果继承Thread类的话,每一个线程都要新建一个实例对象。

    4)实现Callable接口,允许线程执行完成之后,返回执行结果。

    展开全文
  • 不足:由于java为单继承,若使用线程类已经有个父类,则不能使用该方式创建线程。 public class ThreadEx extends Thread { public void run() { for (int i = 0; i ; i++) { System.out.println(Thread.current...

    1.实现Runnable接口,重载run(),无返回值

    package thread;

    public class ThreadRunnable implements Runnable {

    public void run() {

    for (int i = 0; i < 10; i++) {

    System.out.println(Thread.currentThread().getName() + ":" + i);

    }

    }

    }

    package thread;

    public class ThreadMain {

    public static void main(String[] args) throws Exception {

    ThreadRunnable threadRunnable1 = new ThreadRunnable();

    ThreadRunnable threadRunnable2 = new ThreadRunnable();

    ThreadRunnable threadRunnable3 = new ThreadRunnable();

    ThreadRunnable threadRunnable4 = new ThreadRunnable();

    Thread thread1 = new Thread(threadRunnable1);

    Thread thread2 = new Thread(threadRunnable2);

    Thread thread3 = new Thread(threadRunnable3);

    Thread thread4 = new Thread(threadRunnable4);

    thread1.start();

    thread2.start();

    thread3.start();

    thread4.start();

    }

    }

    2.继承Thread类,复写run()

    使用时通过调用Thread的start()(该方法是native),再调用创建线程的run(),不同线程的run方法里面的代码交替执行。

    不足:由于java为单继承,若使用线程类已经有个父类,则不能使用该方式创建线程。

    public class ThreadEx extends Thread {

    public void run() {

    for (int i = 0; i < 10; i++) {

    System.out.println(Thread.currentThread() + ":" + i);

    }

    }

    }

    public class ThreadMain {

    public static void main(String[] args)

    {

    ThreadEx threadEx = new ThreadEx();

    threadEx.start();

    }

    }

    3.实现Callable接口,通过FutureTask/Future来创建有返回值的Thread线程,通过Executor执行

    补充:与实现Runnable接口类似,都是实现接口,不同的是该方式有返回值,可以获得异步执行的结果。

    延伸:FutureTask是类,Future是接口。

    package thread;

    import java.util.concurrent.*;

    public class ThreadCallable {

    public static void main(String[] args) throws Exception {

    FutureTask futureTask = new FutureTask(new Callable() {

    public Integer call() throws Exception {

    for (int i = 0; i < 10; i++) {

    System.out.println(Thread.currentThread().getName() + ":" + i);

    }

    return 1;

    }

    });

    Executor executor = Executors.newFixedThreadPool(1);

    ((ExecutorService) executor).submit(futureTask);

    //获得线程执行状态

    System.out.println(Thread.currentThread().getName() + ":" + futureTask.get());

    }

    }

    4.使用Executors创建ExecutorService,入参Callable或Future

    补充:适用于线程池和并发

    package thread;

    import java.util.concurrent.Callable;

    import java.util.concurrent.Executors;

    import java.util.concurrent.ThreadFactory;

    import static java.lang.Thread.sleep;

    public class ThreadExecutors {

    private final String threadName;

    public ThreadExecutors(String threadName) {

    this.threadName = threadName;

    }

    private ThreadFactory createThread() {

    ThreadFactory tf = new ThreadFactory() {

    public Thread newThread(Runnable r) {

    Thread thread = new Thread();

    thread.setName(threadName);

    thread.setDaemon(true);

    try {

    sleep(1000);

    }

    catch (InterruptedException e) {

    e.printStackTrace();

    }

    return thread;

    }

    };

    return tf;

    }

    public Object runCallable(Callable callable) {

    return Executors.newSingleThreadExecutor(createThread()).submit(callable);

    }

    public Object runFunture(Runnable runnable) {

    return Executors.newSingleThreadExecutor(createThread()).submit(runnable);

    }

    }

    package thread;

    import java.util.concurrent.*;

    public class ThreadMain {

    public static void main(String[] args) throws Exception {

    ThreadExecutors threadExecutors = new ThreadExecutors("callableThread");

    threadExecutors.runCallable(new Callable() {

    public String call() throws Exception {

    return "success";

    }

    });

    threadExecutors.runFunture(new Runnable() {

    public void run() {

    System.out.println("execute runnable thread.");

    }

    });

    }

    }

    5 Runnable接口和Callable接口区别

    1)两个接口需要实现的方法名不一样,Runnable需要实现的方法为run(),Callable需要实现的方法为call()。

    2)实现的方法返回值不一样,Runnable任务执行后无返回值,Callable任务执行后可以得到异步计算的结果。

    3)抛出异常不一样,Runnable不可以抛出异常,Callable可以抛出异常。

    6 Callable返回值意义在哪儿,不要返回值可以吗,什么时候需要用到返回值?

    首先Callable是线程异步执行的结果状态,如果有两个线程A和B,B中的某个业务逻辑中需要确定A结束后才能进行,那么就需要获得线程A的执行结果。

    设计背景:一个任务需要进行一系列操作,比如拷贝大量的基础数据,以及解析数据,并入库,由于数量大,整个过程需要持续十秒左右,用户体验差,需要降低到2~5s。

    设计思路:经过分解过程,将拷贝数据分为一个过程,同时涵盖部分解析数据功能,剩下解析数据划为一个过程,两个过程异步执行,其中最后一个任务状态入库时需要将所有业务操作都执行完成后更新,此时就需要用到线程中的返回值。

    展开全文
  • Java创建线程的方式

    2018-04-23 21:18:13
    1、创建线程的方式 继承Thread,重写run方法 实现Runnable接口,重写run方法 实现Callable接口,重写call方法(执行完任务之后能够获取执行结果) 2、具体实现及使用 2.1、继承Thread,重写run方法 ...

    1、创建线程的方式

    • 继承Thread,重写run方法
    • 实现Runnable接口,重写run方法
    • 实现Callable接口,重写call方法(在执行完任务之后能够获取执行结果)

    2、具体实现及使用

    2.1、继承Thread,重写run方法

    public class MyThread extends Thread {
    
        @Override
        public void run() {
            for (int x = 0; x < 200; x++) {
                System.out.println(x);
            }
        }
    
    }
    
    public class MyThreadDemo {
        public static void main(String[] args) {
            // 创建两个线程对象
            MyThread my1 = new MyThread();
            MyThread my2 = new MyThread();
    
            my1.start();
            my2.start();
        }
    }

    2.2、实现Runnable接口,重写run方法

    public class MyRunnable implements Runnable {
    
        @Override
        public void run() {
            for (int x = 0; x < 100; x++) {
                System.out.println(x);
            }
        }
    
    }
    
    public class MyRunnableDemo {
        public static void main(String[] args) {
            // 创建MyRunnable类的对象
            MyRunnable my = new MyRunnable();
    
            Thread t1 = new Thread(my);
            Thread t2 = new Thread(my);
    
            t1.start();
            t2.start();
        }
    }

    3、一些问题

    3.1、run()和start()方法区别

    • run():仅仅是封装被线程执行的代码,直接调用是普通方法,只会执行同一个线程中的任务,而不会启动新线程。
    • start():首先启动了线程,然后再由jvm去调用该线程的run()方法。

    3.2、我们应该使用哪种方式创建线程

    一般情况下通过实现Runnable接口创建线程,原因如下:

    • 可以避免java中的单继承的限制
    • 应该将并行运行任务和运行机制解耦合。如果通过继承Thread类创建,并且调用start()方法启动线程,那么当有很多任务时,要为每个任务创建一个独立的线程,代价太大。这个问题可以通过线程池解决。

    当执行完任务后需要获取执行结果,可以通过实现Callable接口创建线程。

    展开全文
  • 缺点:效率低,获取T线程执行结果的时候,当前线程会受到阻塞,所以效率低。 例子: import java.util.concurrent.Callable; import java.util.concurrent.FutureTask;//JUC包下的,属于java的并发包。 public ...

    实现线程的一种方法:
    /
    实现Callable接口
    这种方式的优点:可以获取到线程的执行结果。
    缺点:效率低,在获取T线程执行结果的时候,当前线程会受到阻塞,所以效率低。
    例子:

    import java.util.concurrent.Callable;
    import java.util.concurrent.FutureTask;//JUC包下的,属于java的并发包。
    
    public class ThreadTest11 {
        public static void main(String[] args)throws Exception {
            //第一步:创建一个“未来任务类”对象。
            //参数很重要,需要给一个Callable接口的实现类,下面用的是匿名内部类的方式。
            FutureTask task = new FutureTask(new Callable() {
                @Override
                public Object call() throws Exception {
                    //此处模拟执行一个有执行结果的程序。
                    System.out.println("call method begin");
                    Thread.sleep(1000*10);
                    System.out.println("call method end");
                    int a = 100;
                    int b = 200;
                    return a+b;//自动装箱
                }
            });
            //创建线程对象,需要将上面的未来任务类对象传进去。
            Thread t = new Thread(task);
            //启动线程
            t.start();
            //这是在main方法中,在主线程中。
            //get()方法就可以获取t线程的返回结果,当然就会阻塞当前线程的进行。
            Object obj = task.get();
            System.out.println(obj);
    
        }
    
    }
    
    
    展开全文
  • new SubThread() 是主线程路径下开辟一条新的子路径,开启新线程,子线程运行run()方法,cpu会随机选择主或子线程进行运行,运行结果也是随机性的
  • java1.5版本开始,我们就Thread和Runnable两种方式创建线程基础上,新增加了使用Callable和Future创建线程,很好地解决了前者执行完任务之后无法获取执行结果,而如果需要获取执行结果,就必须通过共享变量...
  • 从Java1.5版本开始,就提供了 Callable 和 Future 来创建线程,这种方式也是在Java程序员面试中经常会被问到的问题。 上一小节介绍了Thread和Runnable两种方式创建线程,不过这两种方式创建线程都有一个缺陷:在执行...
  • 有的时候我们需要同时执行两个任务,但是任务A需要等待任务B的结果才能继续执行,如果一般情况下,我们需要先等待B执行完毕再执行A,这样串行执行比较耗费时间,总耗时就是B的时间+A的时间。 long start = ...
  • Java 5.0 java.util.concurrent 提供了一个新的创建执行线程的方式:Callable 接口Callable 接口类似于 Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。但是 Runnable 不会返回结果,并且无法抛...
  • 直接继承Thread、实现Runnable接口,执行完任务之后无法获取执行结果。 但是通过 Callable 和 Future可以获取执行结果。 2、普通方式实现Callable接口 import java.util.Arrays; import java.util.List; ...
  • 实际应用中,我们经常用到多线程,如车站的售票系统,车站的各个售票口相当于各个线程。当我们做这个系统的时候可能会想到两种方式来实现,继承Thread类或实现Runnable接口,现在看一下这两种方式实现的两种结果。...
  • Java前台线程与后台线程上一篇博客main()方法中,创建并启动了四个新的线程后,main()方法中的代码执行完毕,此时,方法会结束,main线程也就随之结束了通过程序的运行结果可以看出,虽然,main线程结束了,但是...
  • 如何创建线程 第一 继承java.lang.Thread 类,然后覆盖 Run 方法 第二 Run 方法中实现 线程执行代码即可 需要注意 多线程 是抢占式 响应,按照优先级来 若没有默认的优先级,则每次都会出现不同的运行结果。 多...
  • 今晚看Think In Java的时候,看到后台线程这一小节,突然有个想法,如果一个守护线程里面创建一个非守护线程(不显示的设置setDaemon(true)),那么创建的非守护线程是否也变成了守护线程。 代码如下 package ...
  • 最近做代码优化时学习和研究了下JAVA线程的使用,线程类的一些方法辉哥也已经发过了,所以只是对线程的实现做个总结 一、Java线程实现方式主要有三种: 1、继承Thread类 2、实现Runnable接口 3、使用...
  • 展开全部java创建线程在调用start方法后,进入就绪e69da5e6ba903231313335323631343130323136353331333361303539状态,但通常不会马上分配到CPU,处于线程就绪队列,需要等待时间片轮转到该线程获得CPU后才能执行...
  • 概念二、创建线程1.项目结构2.需要执行的类People3.继承Thread4. 实现runnable5.实现Callable6.main方法三、总结1.运行结果2.结果分析3.结语 一、线程的概念 1.概念 1.1进程是一个应用程序的运行,运用一个应用...
  • 一:Java创建线程方式继承Thread类或者实现Runnable接口。但是Runnable 的 run() 方法是不带返回值的,那如果我们需要一个耗时任务执行完之后给予返回值,应该怎么做呢?第一种方法: Runnable 的实现类中设置一...
  • 创建线程有三种方式:实现Runnable接口、继承Thread类、实现CallAble接口,代码如下:对应的运行结果如下:有些小伙伴可能会对结果二和结果三产生疑问,现在解释如下(个人理解): 程序是调用了两个线程来并发执行...
  • Java创建线程的方式有两种:1)继承 Thread 类 2)实现 Runnable 接口 3)实现 FutureTask 接口 前两种方式创建的线程都无法获取线程的执行结果,而通过 FutureTask 方式实现的线程可以获取线程执行的结果。 ...
  • Java 5.0 java.util.concurrent 提供了一个新的创建执行线程的方式:Callable接口 Callable 接口类似于Runnable,两者都是为那些其实例肯能被另一个线程设计的。但是Runnable不会返回结果,并且无法抛出经过检查...
  • 方式一览 方式一 演练 定义一个线程类,继承了的 测试类 实例化自定义的线程类为对象 调用对象的start方法 主线程也打印内容 执行的结果
  • 传统的同步开发模式下,当我们调用一个函数时,通过这个函数的参数将数据传入,并通过这个函数的返回值来返回最终...Java多线程:向线程传递参数的三种方法一、通过构造方法传递数据在创建线程时,必须要建立一个...
  • 创建线程的方式有四种: 1.继承Thread类 2.实现Runnable接口 3.实现Callable接口 4.使用线程池 这四种方法中,根据《Effective Java》一书中指出优先使用线程池 继承Thread类和实现Runnable接口两种方法中...
  • Java线程

    2018-08-28 22:09:22
    Java多线程技能 关键技术点: 线程的启动 如何使线程暂停 ...继承Thread和实现Runnable接口两种创建线程的方式工作时的性质是一样的,没有本质的区别 使用多线程技术时,代码的运行结果与代码执...
  • 我使用Observable.create()创建一个observable来对调度程序执行一些工作(例如Schedulers.io(),然后AndroidSchedulers.mainThread()上返回一个结果.val subscription = observable {try {// perform action ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,291
精华内容 516
关键字:

在java创建线程结果

java 订阅