转载

Java多线程实现的两种方式(源自官方)

来源概述

刚刚在准备面试刷题。于是想起好像有一个关于“Java县城实现的方式”,于是百度(虽然盛传*度已死)、谷歌。然后结果。。。

[站外图片上传中...(image-10f8bf-1569247170008)]

Java多线程实现的两种方式(源自官方)

这坑不能忍啊!回答还能不能再给力一些。

这要是笔试或者面试有这个问题的话,那估计多少个面试机会都会死得不能再死了,还不知道到底根本原因是啥!!! 这就相当可怕了。

于是找到官方 java tutorials 找结果:

Java多线程实现的两种方式(源自官方)

意思就是实现线程只有两种方式

实现方式

第一种 实现 Runnalble 接口

Provide a Runnable object. The Runnable interface defines a single method, run, meant to contain the code executed in the thread. The Runnable object is passed to the Thread constructor, as in the HelloRunnable example:

public class HelloRunnable implements Runnable {

    public void run() {
        System.out.println("Hello from a thread!");
    }

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

}

第二种 继承 Thread 类

Subclass Thread. The Thread class itself implements Runnable, though its run method does nothing. An application can subclass Thread, providing its own implementation of run, as in the HelloThread example:

public class HelloThread extends Thread {

    public void run() {
        System.out.println("Hello from a thread!");
    }

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

}

小提示

Notice that both examples invoke Thread.start in order to start the new thread.

  1. 启动用线程对象的start方法调用,正如上面两个示例程序一样。
  2. 实现代码都是写在run方法里面,或者被run方法直接或间接调用。

疑问

  1. Thread 方法也是通过实现 Runnable 接口来实现的,是不是可以归结为一种呢?

官方两种,至于程序员自己嘛 哼哼哼 都懂都懂哈!!!

  1. 带返回值的线程实现方式(FutureTask + 实现 Callable 接口)、基于线程池的方式(Executors.new.*ThreadPool)、内部类实现方式不算么?

答:这些都是拓展了上面两种的的其中一种,内部类是那那种方式,其它如:

  • 带返回值的线程实现方式(FutureTask + 实现 Callable 接口)
FutureTask 实现了 Runnable接口,其中就包括了调用接口Callable 接口的 call 方法,所以是可以通过实现Callable 就可以实现线程,那还是第一种线程实现方式。FutureTask 部分代码如下:
public class FutureTask<V> implements RunnableFuture<V> {
  // 重写了run方法 只是内部实现
  public void run() {
        if (state != NEW ||
            !UNSAFE.compareAndSwapObject(this, runnerOffset,
                                         null, Thread.currentThread()))
            return;
        try {
            Callable<V> c = callable; // 使用到Callable
            if (c != null && state == NEW) {
                V result;
                boolean ran;
                try {
                    result = c.call();  // 运行 call 方法
                    ran = true;
                } catch (Throwable ex) {
                    result = null;
                    ran = false;
                    setException(ex);
                }
                if (ran)
                    set(result);  // 设置返回值
            }
        } finally {
            // runner must be non-null until state is settled to
            // prevent concurrent calls to run()
            runner = null;
            // state must be re-read after nulling runner to prevent
            // leaked interrupts
            int s = state;
            if (s >= INTERRUPTING)
                handlePossibleCancellationInterrupt(s);
        }
    }
}
  • 基于线程池的方式(Executors.new.*ThreadPool)

其中 Executors.new.*ThreadPool 都是通过新建 ThreadPoolExecutor 累来实现的,而表示为工作任务的队列,所以这种也是第一种线程实现方式。 Executors部分代码如下:

public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
      public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {// 工作线程队列 实现 Runnable 接口
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

总结

网上的坑还是有,一不小心就掉进去了。像这个显而易见的线程实现问题还是很容易知道有问题的,找出正解也没什么太大难度。但是想想我们平常遇到的问题是那么“层出不穷”?网上搜索到的解决方案又是如此“百花齐放”(管你对不对)。所以凡是问题都不要留心眼,根本不够用。

  • 学习资料,尽量从官方文档中学习,经典教材中学习;
  • 解决问题,多方搜索,各种推敲,免不了各种查源码;

----致困扰本帅多年的简单线程实现方式问题

原文  https://segmentfault.com/a/1190000020472895
正文到此结束
Loading...