高并发实战--笔记

版权声明:转载请联系博主 https://blog.csdn.net/weixin_43647224/article/details/86059865

创建线程池

package com.syn.syn1;

import org.apache.catalina.Executor;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Auther: zch
 * @Date: 2019/1/8 08:42
 * @Description:
 */
public class ThreadPoolDemo {
    public static void main(String[] args) throws InterruptedException {

        MyTask task = new MyTask();
        ExecutorService executorService = Executors.newFixedThreadPool(5);

        for (int i=0;i<10;i++) {
            executorService.submit(task);
        }

    }

    public static class MyTask implements Runnable {
        @Override
        public void run() {
            System.out.println(System.currentTimeMillis() + ":thread ID:" + Thread.currentThread().getId());

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}

创建newFixedThreadPool为5,添加10个任务。每个任务执行1秒

1546908393485:thread ID:11
1546908393485:thread ID:12
1546908393486:thread ID:13
1546908393486:thread ID:14
1546908393486:thread ID:15
1546908394485:thread ID:11
1546908394485:thread ID:12
1546908394486:thread ID:15
1546908394486:thread ID:13
1546908394486:thread ID:14

前5个任务id与后5个id一致,说明10个任务中,是分2批次执行,符合一个只有5个线程的行为

newScheduledThreadPool() 

 作用:该方法返回一个可以控制线程池内线程定时或周期性执行某任务的线程池。

package com.syn.syn1;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @Auther: zch
 * @Date: 2019/1/8 08:56
 * @Description:
 */
public class ScheduledExecutorServiceDemo {
      public static void main(String[] args) throws InterruptedException
          {

              ScheduledExecutorService ses = Executors.newScheduledThreadPool(10);
              ses.scheduleAtFixedRate(new Runnable() {
                  @Override
                  public void run() {
                      try {

                          Thread.sleep(1000);
                          System.out.println(System.currentTimeMillis() / 1000);
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }
              },0,2, TimeUnit.SECONDS);
          }

}

拓展ThreadPoolExecutor

它提供beforeExecute,afterExecute,terminated 三个接口对线程池进行控制

package com.syn.syn1;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @Auther: zch
 * @Date: 2019/1/8 09:25
 * @Description:
 */
public class ExtThreadPool {
      public static void main(String[] args) throws InterruptedException
          {
              ExecutorService es=new ThreadPoolExecutor(5,5,0L, TimeUnit.MICROSECONDS,new LinkedBlockingDeque<Runnable>()){

                  @Override
                  protected void beforeExecute(Thread t, Runnable runnable) {
                      System.out.println("准备执行:"+((MyTask)runnable).name);
                  }

                  @Override
                  protected void afterExecute(Runnable r, Throwable t) {
                      System.out.println("执行完成");
                  }

                  @Override
                  protected void terminated() {
                      System.out.println("线程池退出");
                  }
              };
              for (int i=0;i<5;i++) {
                  MyTask task = new MyTask("TASK-GEYM-" + i);
                  es.execute(task);
                  Thread.sleep(1000);

              }
              es.shutdown();

          }

    public static class MyTask implements Runnable {
        public String name;

        public MyTask(String name) {
            this.name = name;
        }


        @Override
        public void run() {

            System.out.println("正在执行:" + Thread.currentThread().getId() + "Task Name="+name);
            try {
                Thread.sleep(1000);

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

shutdown不会立即暴力终止所有的任务,等待所有任务执行完成后,再关闭线程池。

提交方式为execute,目的是产生异常栈堆,方便排查问题。

改造ThreadPollExecutor 让它调度任务之前,先保存提交任务线程的堆栈信息。

import java.util.concurrent.*;

/**
 * @Auther: zch
 * @Date: 2019/1/8 10:02
 * @Description:
 */
public class TraceThreadPollExecutor extends ThreadPoolExecutor {
    public TraceThreadPollExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }

    @Override
    public void execute(Runnable command) {
        super.execute(warp(command,clientTrace(),Thread.currentThread().getName()));
    }

    @Override
    public Future<?> submit(Runnable task) {
        return super.submit(warp((task), clientTrace(), Thread.currentThread().getName()));
    }

    private Exception clientTrace() {
        return new Exception("Client stack trace");
    }

    private Runnable warp(final Runnable task, final Exception cilentStask, String clientThreadName) {
        return new Runnable() {
            @Override
            public void run() {
                try {
                    task.run();
                } catch (Exception e) {
                    cilentStask.printStackTrace();
                    throw e;
                }
            }
        };
    }
      public static void main(String[] args) throws InterruptedException
          {
              ThreadPoolExecutor pools=new TraceThreadPollExecutor(0,Integer.MAX_VALUE,0L,TimeUnit.SECONDS,new SynchronousQueue<Runnable>());
              for (int i=0;i<5;i++) {
                  pools.execute(()-> System.out.println("helo"+Thread.currentThread().getId()));
              }

          }
}

猜你喜欢

转载自blog.csdn.net/weixin_43647224/article/details/86059865