zoukankan      html  css  js  c++  java
  • Java中实现线程的方式

    Java中实现线程的方式

    Java中实现多线程的方式的方式中最核心的就是 run()方法,不管何种方式其最终都是通过run()来运行。

    Java刚发布时也就是JDK 1.0版本提供了两种实现方式,一个是继承Thread类,一个是实现Runnable接口。两种方式都是去重写run()方法,在run()方法中去实现具体的业务代码。

    但这两种方式有一个共同的弊端,就是由于run()方法是没有返回值的,所以通过这两方式实现的多线程读无法获得执行的结果。

    为了解决这个问题在JDK 1.5的时候引入一个Callable<V>接口,根据泛型V设定返回值的类型,实现他的call()方法,可以获得线程执行的返回结果。

    虽然call()方法可以获得返回值,但它需要配合一个Future<V>才能拿到返回结果,而这个Future<V>又是继承了Runnable的一个接口。 通过查阅源码就可以发现Future<V>的实现FutureTask<V>其在做具体业务代码执行的时候仍是在run()里面实现的。

    FutureTask 源码片段:

    public void run() {
            if (state != NEW ||
                !UNSAFE.compareAndSwapObject(this, runnerOffset,
                                             null, Thread.currentThread()))
                return;
            try {
                Callable<V> c = callable;
                if (c != null && state == NEW) {
                    V result;
                    boolean ran;
                    try {
                        result = c.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);
            }
        }
    

    Java多线程实现方式的代码示例:

    通过继承Thread类实现

    public class ThreadTest {
    
      public static void main(String[] args) throws Exception {
        Thread myThread = new MyThread();
        myThread.setName("MyThread-entends-Thread-test");
        myThread.start();
    
      }
    }
    
    class MyThread extends Thread {
    
      @Override
      public void run() {
        System.out.println("Thread Name:" + Thread.currentThread().getName());
      }
    }
    

    通过实现Runnable接口实现

    public class ThreadTest {
    
      public static void main(String[] args) throws Exception {
    
        MyRunnableThread myRunnable = new MyRunnableThread();
        Thread myRunnableThread = new Thread(myRunnable);
        myRunnableThread.setName("MyThread-implements-Runnable-test");
        myRunnableThread.start();
      }
    }
    
    class MyRunnableThread implements Runnable {
    
      @Override
      public void run() {
        System.out.println("Thread Name:" + Thread.currentThread().getName());
      }
    }
    

    通过实现Callable接口实现

    public class ThreadTest {
    
      public static void main(String[] args) throws Exception {
    
        Callable<String> myCallable = new MyCallableThread();
        FutureTask<String> futureTask = new FutureTask<>(myCallable);
        Thread myCallableThread = new Thread(futureTask);
        myCallableThread.setName("MyThread-implements-Callable-test");
        myCallableThread.start();
        System.out.println("Run by Thread:" + futureTask.get());
    
        //通过线程池执行
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.submit(futureTask);
        executorService.shutdown();
        System.out.println("Run by ExecutorService:" + futureTask.get());
      }
    }
    
    class MyCallableThread implements Callable<String> {
    
      @Override
      public String call() throws Exception {
        return Thread.currentThread().getName();
      }
    }
    

    当然由于线程的创建和销毁需要消耗资源,Java中还通过了许多线程池相关的API,上述示例中ExecutorService就是线程池API中的一个,关于线程池的详细内容将会在下一篇继续,欢迎大家关注。

  • 相关阅读:
    vim常用命令总结
    深度学习之 GAN 进行 mnist 图片的生成
    javascript 中的类型
    架构设计小思
    [前端]如何让图片等比例缩放,同时撑满父级容器的长或宽
    深度学习之 seq2seq 进行 英文到法文的翻译
    深度学习之 cnn 进行 CIFAR10 分类
    深度学习之 rnn 台词生成
    深度学习之 mnist 手写数字识别
    前端页面,使用 dom 鼠标拖拽画一个矩形和监听键盘
  • 原文地址:https://www.cnblogs.com/coding-diary/p/11172924.html
Copyright © 2011-2022 走看看