线程

线程

线程的四种状态

  • New:线程刚刚创建,还未加入线程调度
  • Runnable:就绪态,调用 start() 后,线程加入线程调度。此时,只要获取到 CPU 时间片,就会进入运行态
  • Running:运行态,线程获取到 CPU 时间片后,就会被 CPU 运行。可以通过 yield() 主动让出时间片,会使得线程返回就绪态
  • Blocked:阻塞态,此时线程需要等待释放信号才能进入就绪态,如等待用户输入、等待锁被解除
  • Dead:线程结束

线程中的变量

// 获取当前线程Thread thread = Thread.currentThread();
// 获取线程 IDlong id = thread.getId();
// 获取线程 Name String name = thread.getName();
// 获取线程优先级int priority = thread.getPriority();
publicfinalstaticint MIN_PRIORITY = 1;
publicfinalstaticint NORM_PRIORITY = 5;
publicfinalstaticint MAX_PRIORITY = 10;
// 判定线程是否为守护线程boolean isDaemon = thread.isDaemon();
// 判定线程是否被中断;被中断会进入阻塞 Blocked 状态boolean isInterrupted = thread.isInterrupted();
// 判定线程是否存活boolean isAlive = thread.isAlive();

创建线程的方式

  • 继承Thread类
  • 实现Runnable接口
  • 实现Callable接口
  • 使用线程池创建
    1.submit和excute有什么区别
    submit支持实现Runnable和Callable接口的线程
    不调用Future的get()方法会吃掉异常
    excute只支持Runnable接口的现场
public class ThreadStudy {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Thread1 tread1 = new Thread1();
        tread1.setName("线程一");
        tread1.start();
        Thread thread2 = new Thread(new Thread2());
        thread2.setName("线程二");
        thread2.start();
        FutureTask<String> task = new FutureTask<String>(new Thread3());
        Thread thread3 = new Thread(task);
        thread3.setName("线程三");
        thread3.start();
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        System.out.println("-----------------------");
        executorService.execute(new Thread2());
        executorService.execute(new Thread1());
        executorService.submit(new Thread3());
        Future<String> submit = executorService.submit(new Thread3());
        String result = submit.get();
        System.out.println(result);

        Executors.newCachedThreadPool();
        Executors.newSingleThreadExecutor();
        executorService.shutdown();
    }
}
class Thread1 extends Thread{
    @Override
    public void run() {
        System.out.println("这是继承Thread创建的线程:"+Thread.currentThread().getName());
    }
}
class Thread2 implements  Runnable{
    @Override
    public void run() {
        System.out.println("这是实现Runnable创建的线程:"+Thread.currentThread().getName());
    }
}

class Thread3 implements Callable {

    @Override
    public String call() throws Exception {
        System.out.println("这是实现Callable创建的线程:"+Thread.currentThread().getName());
        return "这是实现Callable创建的线程:"+Thread.currentThread().getName();
    }
}

线程池创建的线程

public ThreadPoolExecutor(int corePoolSize, // 核心线程池大小
                            int maximumPoolSize,  // 最大线程池大小
                            long keepAliveTime,  // 线程最大空闲时间
                            TimeUnit unit,  // 时间单位
                            BlockingQueue<Runnable> workQueue, // 线程等待队列
                            ThreadFactory threadFactory,  // 线程创建工程
                            RejectedExecutionHandler handler ) { //拒绝策列
      if (corePoolSize < 0 ||
          maximumPoolSize <= 0 ||
          maximumPoolSize < corePoolSize ||
          keepAliveTime < 0)
          throw new IllegalArgumentException();
      if (workQueue == null || threadFactory == null || handler == null)
          throw new NullPointerException();
      this.corePoolSize = corePoolSize;
      this.maximumPoolSize = maximumPoolSize;
      this.workQueue = workQueue;
      this.keepAliveTime = unit.toNanos(keepAliveTime);
      this.threadFactory = threadFactory;
      this.handler = handler;
  }
  • newFixedThreadPool

    • 参数分析:核心线程数和最大线程数相同,线程等待队列无限大
    • 使用场景:Web服务器瞬间削峰,持续高峰情况需要注意队列阻塞
public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}
  • newCacheThreadPool

    • 参数分析:核心线程池为0,最大线程数无限大,线程最大空闲时间60秒
    • 使用场景:快速处理大量耗时较短的任务,如Netty的NIO接受请求时,可使用CachedThreadPool。
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>(),
                                  threadFactory);
}
  • newSchedulThreadPool

参数分析:传入核心线程

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
}
public ScheduledThreadPoolExecutor(int corePoolSize) {
    super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
          new DelayedWorkQueue());
}
  • newSingeThreadExecutor

参数分析:依靠FinalizableDelegatedExecutorService执行操作

public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
}
static class FinalizableDelegatedExecutorService
    extends DelegatedExecutorService {
    FinalizableDelegatedExecutorService(ExecutorService executor) {
        super(executor);
    }
    protected void finalize() {
        super.shutdown();
    }
}
  • newSingThreadSchedulExecutor

参数:线程工厂

public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {
    return new DelegatedScheduledExecutorService
        (new ScheduledThreadPoolExecutor(1, threadFactory));
}
static class DelegatedScheduledExecutorService
        extends DelegatedExecutorService
        implements ScheduledExecutorService {
    private final ScheduledExecutorService e;
    DelegatedScheduledExecutorService(ScheduledExecutorService executor) {
        super(executor);
        e = executor;
    }
    public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
        return e.schedule(command, delay, unit);
    }
    public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) {
        return e.schedule(callable, delay, unit);
    }
    public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) {
        return e.scheduleAtFixedRate(command, initialDelay, period, unit);
    }
    public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) {
        return e.scheduleWithFixedDelay(command, initialDelay, delay, unit);
    }
}

自定义线程池

public class ThreadTest {

    public static void main(String[] args) throws InterruptedException, IOException {
        int corePoolSize = 2;
        int maximumPoolSize = 4;
        long keepAliveTime = 10;
        TimeUnit unit = TimeUnit.SECONDS;
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(2);
        ThreadFactory threadFactory = new NameTreadFactory();
        RejectedExecutionHandler handler = new MyIgnorePolicy();
        ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit,
                workQueue, threadFactory, handler);
        executor.prestartAllCoreThreads(); // 预启动所有核心线程
        
        for (int i = 1; i <= 10; i++) {
            MyTask task = new MyTask(String.valueOf(i));
            executor.execute(task);
        }

        System.in.read(); //阻塞主线程
    }

    static class NameTreadFactory implements ThreadFactory {

        private final AtomicInteger mThreadNum = new AtomicInteger(1);

        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r, "my-thread-" + mThreadNum.getAndIncrement());
            System.out.println(t.getName() + " has been created");
            return t;
        }
    }

    public static class MyIgnorePolicy implements RejectedExecutionHandler {

        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            doLog(r, e);
        }

        private void doLog(Runnable r, ThreadPoolExecutor e) {
            // 可做日志记录等
            System.err.println( r.toString() + " rejected");
//          System.out.println("completedTaskCount: " + e.getCompletedTaskCount());
        }
    }

    static class MyTask implements Runnable {
        private String name;

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

        @Override
        public void run() {
            try {
                System.out.println(this.toString() + " is running!");
                Thread.sleep(3000); //让任务执行慢点
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        public String getName() {
            return name;
        }

        @Override
        public String toString() {
            return "MyTask [name=" + name + "]";
        }
    }
}

线程池的大小

IO密集型
CPU密集型
Runtime.getRuntime().availableProcessors():获取CPU的核数

结论

总结,通过自定义线程池,我们可以更好的让线程池为我们所用,更加适应我的实际场景。

posted @ 2020-04-22 09:43  不爱吃西红柿  阅读(1146)  评论(0编辑  收藏  举报