Java多线程:线程的创建与启动

2020-06-06  本文已影响0人  垃圾简书_吃枣药丸

# 面试题:

# Java中创建线程的方式

image.png
/**
 * 通过继承Thread类,重写run()方法实现的线程
 *
 * @author futao
 * @date 2020/6/4
 */
public class ByThread extends Thread {

    @Override
    public void run() {
        System.out.println("通过继承Thread实现的多线程:" + Thread.currentThread().getName());
    }

    public static void main(String[] args) {
        new ByThread().start();
    }
}


/**
 * 通过实现Runnable接口,重写run()方法实现的线程
 *
 * @author futao
 * @date 2020/6/4
 */
public class ByRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("通过实现接口Runnable实现的多线程:" + Thread.currentThread().getName());
    }

    public static void main(String[] args) {
        new Thread(new ByRunnable()).start();
    }
}

# 核心思想

从源代码的角度来看,创建线程的方式只有一种,唯一的途径就是实例化一个Thread对象,通过thread.start()来启动线程。而继承Thread类和实现Runnable接口,只不过是对方法执行单元(run()方法)的两种不同实现。**

# 两种方式的对比:

  1. 从代码架构角度:使用Runnable接口得我方式可以将线程的创建/停止/状态管理等与真正的业务逻辑解耦,使Runnable子类只需要关注真正的业务即可。
  2. 从性能损耗角度:使用继承Thread的方法,每次执行任务都需要启动一个新的线程,创建一个新的Thread实例,任务执行完毕之后还需要进行销毁。对性能的损耗比较严重。而实现Runnable接口的方式,可以实现对线程的复用,每次给线程传递不同的任务(Runnable实例)即可,不需要频繁的创建与销毁线程。(参考线程池的执行过程
  3. 从可扩展性角度:Java只支持单继承,所以实现Runnable接口的方式更好,避免继承的局限,方便后续对程序进行扩展。

# Q: 如果同时继承Thread类和实现Runnable接口,会发生什么?

/**
 * @author futao
 * @date 2020/6/4
 */
public class Both {

    public static void main(String[] args) {
        new Thread(() -> {
            //通过lambda表达式创建Runnable子类对象
            System.out.println("来自实现Runnable接口的run()方法");
        }) {
            //Thread的匿名内部类,直接重写Thread父类的run()方法
            @Override
            public void run() {
                System.out.println("来自重写Thread类的run()方法");
            }
        }.start();
    }
}
image.png
  @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }

# 错误观点

       ExecutorService executorService = Executors.newCachedThreadPool(new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r);
            }
        });
/**
 * @author futao
 * @date 2020/6/6.
 */
public class CallableFutureTask {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<String> task = new FutureTask<>(new Callable<String>() {
            @Override
            public String call() throws Exception {
                System.out.println("666");
                Thread.sleep(3000L);
                return Thread.currentThread().getName();
            }
        });
        new Thread(task).start();
        //将会阻塞,直到线程任务执行完毕
        System.out.println(task.get());
    }
}
image.png
image.png

# 线程的启动

# 本文源代码

上一篇下一篇

猜你喜欢

热点阅读