zoukankan      html  css  js  c++  java
  • 多线程(一)

    java的1.5后,JDK 增加了一个包Concurrent,为我们的多线程程序的编写带来了很大的方便。这个主要是把以前使用多线程的知识梳理一下。

    首先需要用到的类是java.util.concurrent.Executors, 由它来生成线程执行器java.util.concurrent.ExecutorService,然后根据需要可以用不同的方式运行线程,例如:单个任务可以用executorService.submit(task)或者execute(task);前者是ExecutorService接口就有的方法,任务执行完以后可以返回值,后者是没有返回值。当然这两者区别还是蛮大的,前者一定会将Runnable任务包装成FutureTask,后者就不一定了。多个任务可以用invokeAll/invokeAny提交执行。

    ExecutorService es = Executors.newSingleThreadExecutor();
    Future<String> r = es.submit(new Task());
    es.shutdown();
    try {
              r.get();//get result
    } catch (InterruptedException e) {
                //
    } catch (ExecutionException e) {
                //
    }

    更加详细点的代码:

    public class MyThread extends Thread {
         public MyThread(String string) {
             super(string);
             super.setName(string);
         }
        @Override
         public void run() {
             System.out.println(this.getName() + "开始执行。。。");
             try {
                 sleep(101);
                 System.out.println(this.getName() + "执行结束");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
             
         }
    }
    public static void main(String[] args) throws InterruptedException, ExecutionException{
            ExecutorService signalThread = Executors.newSingleThreadExecutor();
            MyThread threadTest = new MyThread("First test1");
            MyThread threadTest2 = new MyThread("First test2");
            signalThread.execute(threadTest);
            Future<?> result = signalThread.submit(threadTest2);
            signalThread.shutdown();
            Thread.sleep(500);
            if(result.isDone()){
                System.out.println(result.get());
            }
            if(!threadTest2.isAlive()){
                System.out.println(result.get());
            }
            
        }

    结果:

    First test1开始执行。。。
    First test1执行结束
    First test2开始执行。。。
    First test2执行结束
    null
    null

    java.util.concurrent.Executors 这个类就像是操作数组一样的类Arrays,查看该类的说明,主要提供了java concurrent 包中ExecutorExecutorServiceScheduledExecutorServiceThreadFactoryCallable的工厂和实用方法。阅读其代码也不多,

    发现他创建线程执行器大致分为两种,一种是ThreadPoolExecutor,另一种ThreadPoolExecutor/ScheduledThreadPoolExecutor包装以后的线程执行器;

    创建Callable主要有两种,一是将Runnable适配一下返回RunnableAdapter,另一是包装了Callable的PrivilegedCallable;创建ThreadFactory也主要是两种,都是其内部类,一是DefaultThreadFactory,另一是PrivilegedThreadFactory;总之,他可以看作工厂方法类,其他创建的ThreadFactory、Callable可以先放放。

      Executors创建的ExecutorService了。产看该接口,该接口集成自父接口:Executor。Executor接口只定义了void execute(Runnable command)方法,用来执行提交的任务。而ExecutorService除了execute方法之外,还定义了submit,invorkAll,invokeAny,shutdwon等等方法,主要用来执行并跟踪多个异步任务,终止管理等。AbstractExecutorService类提供了ExecutorService接口除了execute之外其他方法的默认实现。产看其代码,发现真正执行任务的却是他没有实现的execute方法,其他执行线程的方法,如sumbit和invokeAll内部都会调用execute(Runnable)方法,而invokeAny方法在其调用的doInvokeAny方法中还是会在ExecutorCompletionService.submit方法中调用execute(Runnable)方法。

     

    具体代码就不贴了,JDK中都有。这里顺便对submit,invokeAll,invokeAny方法的区别不提了,JDK方法都有注释,比较简单。

    <T> Future<T>  submit(Callable<T> task)
              提交一个返回值的任务用于执行,返回一个表示任务的未决结果的 Future。

    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
              执行给定的任务,当所有任务完成时,返回保持任务状态和结果的 Future 列表。

    <T> T invokeAny(Collection<? extends Callable<T>> tasks)
              执行给定的任务,如果某个任务已成功完成(也就是未抛出异常),则返回其结果。

    要提下,执行的任务。从void execute(Runnable command)的签名可以看出他执行的任务是Runnable,众所周知Runnable任务是没有返回值的,若需要任务的返回值则需要Callable来作为任务,

    这里Concurrent提供了Runnable和Callable的适配器。invokeAll,submit,invokeAny方法中会将Runnable包装成callable来执行。具体:


    参考:http://songzi0206.iteye.com/blog/1207349

  • 相关阅读:
    TSYS2.0 碎片工作原理
    回旋。悲哉、哀哉
    Sql高级操作
    你是我最愛的人
    TSYS2.0标签说明
    TSYS:Tkl_TemplateClass 类调用详解
    CMS设计和CMS选型(内容管理系统)
    TSYS2.0 Beta与Tsys 1.1等众多版本下载
    TsysV1.1 系统文件清单介绍
    伪装成Google Bot突破收费页面
  • 原文地址:https://www.cnblogs.com/zhailzh/p/3971030.html
Copyright © 2011-2022 走看看