• java多线程(二)


    善于思考,拥抱变化,才能拥有未来

    一、Threads 和 Runnables

     1   public void researchThread(){
     2         Runnable task = () -> {
     3             String threadName = Thread.currentThread().getName();
     4             System.out.println("Hello " + threadName);
     5         };
     6 
     7         task.run();
     8 
     9         Thread thread = new Thread(task);
    10         thread.start();
    11 
    12         System.out.println("Done!");
    13     }

      运行结果为:

      Hello main
      Done!
      Hello Thread-0

      或者:

      Hello main
      Hello Thread-0
      Done!

    也可以在线程调用时,加入线程休眠来观察线程调用流程。
    TimeUnit.SECONDS.sleep(1);

    二、ExecutorService

    1. newSingleThreadExecutor

    1   public static void getExceterService1(){
    2         ExecutorService executor = Executors.newSingleThreadExecutor();
    3         executor.submit(() -> {
    4             String threadName = Thread.currentThread().getName();
    5             System.out.println("Hello " + threadName);
    6         });
    7     }

    2. 关闭executors

      /**
         * shutdwon()会等待正在执行的任务执行完
         * shutdownNow()止所有正在执行的任务并立即关闭execuotr
         */
        public static void shutdownExcuterService2(){
            ExecutorService executor = Executors.newSingleThreadExecutor();
            try {
                System.out.println("attempt to shutdown executor");
                executor.shutdown();
                executor.awaitTermination(5, TimeUnit.SECONDS);
            }catch (InterruptedException e) {
                System.err.println("tasks interrupted");
            }finally {
                if (!executor.isTerminated()) {
                    System.err.println("cancel non-finished tasks");
                }
                executor.shutdownNow();
                System.out.println("shutdown finished");
            }
        }

    3.callable提交线程任务-newFixedThreadPool

      public static void testCallable1() throws ExecutionException, InterruptedException {
            Callable<Integer> task = () -> {
                try {
                    TimeUnit.SECONDS.sleep(1);
                    return 123;
                }
                catch (InterruptedException e) {
                    throw new IllegalStateException("task interrupted", e);
                }
            };
    
            ExecutorService executor = Executors.newFixedThreadPool(1);
            Future<Integer> future = executor.submit(task);
    
            System.out.println("future done? " + future.isDone());
    
            Integer result = future.get();
    
            System.out.println("future done? " + future.isDone());
            System.out.print("result: " + result);
        }

      执行结果为:

      future done? false
      future done? true
      result: 123

      注:关闭executor,所有的未中止的future都会抛出异常。

    4. 任何future.get()调用都会阻塞,然后等待直到callable中止。在最糟糕的情况下,一个callable持续运行——因此可以简单的传入一个时长来避免这种情况。

     1   public void getTimeoutException() throws InterruptedException, ExecutionException, TimeoutException {
     2         ExecutorService executor = Executors.newFixedThreadPool(1);
     3 
     4         Future<Integer> future = executor.submit(() -> {
     5             try {
     6                 TimeUnit.SECONDS.sleep(2);
     7                 return 123;
     8             }
     9             catch (InterruptedException e) {
    10                 throw new IllegalStateException("task interrupted", e);
    11             }
    12         });
    13 
    14         future.get(1, TimeUnit.SECONDS);
    15     } 

      会抛出异常:

      java.util.concurrent.TimeoutException
      at java.util.concurrent.FutureTask.get(FutureTask.java:205)
      at com.example.junit.concurrent.LearnCallable.getTimeoutException(LearnCallable.java:51)
      at com.example.junit.concurrent.LearnCallable.main(LearnCallable.java:99)

    5. invokeAll

     1   public void testInvokeAll() throws InterruptedException {
     2         ExecutorService executor = Executors.newWorkStealingPool();
     3 
     4         List<Callable<String>> callables = Arrays.asList(
     5                 () -> "task1",
     6                 () -> "task2",
     7                 () -> "task3");
     8 
     9         executor.invokeAll(callables)
    10                 .stream()
    11                 .map(future -> {
    12                     try {
    13                         return future.get();
    14                     }
    15                     catch (Exception e) {
    16                         throw new IllegalStateException(e);
    17                     }
    18                 })
    19                 .forEach(System.out::println);
    20     }

    6.invokeAny-在等待future对象的过程中,这个方法将会阻塞直到第一个callable中止然后返回这一个callable的结果。

     1   public void testInvokeAny() throws ExecutionException, InterruptedException {
     2 
     3         ExecutorService executor = Executors.newWorkStealingPool();
     4 
     5         List<Callable<String>> callables = Arrays.asList(
     6                 callable("task1", 2),
     7                 callable("task2", 1),
     8                 callable("task3", 3));
     9 
    10         String result = executor.invokeAny(callables);
    11         System.out.println(result);
    12 
    13     }
    14 
    15     private Callable<String> callable(String result, long sleepSeconds) {
    16         return () -> {
    17             TimeUnit.SECONDS.sleep(sleepSeconds);
    18             return result;
    19         };
    20     }

    7.ScheduledExecutorService支持任务调度,持续执行或者延迟一段时间后执行。

     1   public static void testScheduled() throws InterruptedException {
     2         ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
     3 
     4         Runnable task = () -> System.out.println("Scheduling: " + System.nanoTime());
     5         ScheduledFuture<?> future = executor.schedule(task, 3, TimeUnit.SECONDS);
     6 
     7         TimeUnit.MILLISECONDS.sleep(1337);
     8 
     9         long remainingDelay = future.getDelay(TimeUnit.MILLISECONDS);
    10         System.out.printf("Remaining Delay: %sms", remainingDelay);
    11     }
    executor.scheduleAtFixedRate(task, initialDelay, period, TimeUnit.SECONDS);
    scheduleAtFixedRate()并不考虑任务的实际用时。所以,如果你指定了一个period为1分钟而任务需要执行2分钟,那么线程池为了性能会更快的执行。
    executor.scheduleWithFixedDelay(task, 0, 1, TimeUnit.SECONDS);
    scheduleWithFixedDelay()在你不能预测调度任务的执行时长时是很有用的。
  • 相关阅读:
    httpd服务器的真实ip获取难题
    nginx配置文件详解
    nginx基础知识总结
    Web服务并发I/O模型
    chrony时间服务器
    Linux运维之每日小技巧-检测网站状态以及PV、UV等介绍
    Centos7系统下编写systemd脚本设置redis开机自启动
    Kibana中的Coordinate Map地图报索引错误的问题
    apache的php模块讲解以及搭建phpmyadmin管理数据库mysql
    AMP架构补充与wordpress部署
  • 原文地址:https://www.cnblogs.com/award/p/10111989.html
Copyright © 2020-2023  润新知