线程

作者: 请叫我平爷 | 来源:发表于2022-02-17 15:20 被阅读0次

创建线程的方式

1. Thread

public static void main(String[] args) {
    Thread thread = new CusThread();
    thread.start();
}

public static class CusThread extends Thread{
    @Override
    public void run() {
        System.out.println("CusThread run ");
    }
}
  • start()run()区别
    start是启动线程,start是用synchronized修饰的,无法多次调用
    run是运行方法,可以多次调用
public synchronized void start() {}
  • stop():停止,不安全,不建议使用,用interrupt替代,stop不会抛出异常
  • suspend():暂停,不安全,不建议使用
  • resume():重新开始
  • interrupt():只是一个标记,需要线程自己来终止,需要处理抛出的异常
    Thread.interrupt(),静态方法会清楚标记
    Thread.currentThread().isInterrupt(),实例化方法不会清除标记
  • join():等待某个线程执行完毕再继续
    public static void main(String[] args) {
      Thread thread1 = new Thread(()->{
          System.out.println("thread1 start");
          try {
              Thread.sleep(1000);
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
          System.out.println("thread1");
          System.out.println("thread1 end");
      },"1");
    
      Thread thread2 = new Thread(()->{
          System.out.println("thread2 start");
          try {
              Thread.sleep(1000);
              thread1.join();
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
          System.out.println("thread2");
          System.out.println("thread2 end");
      },"2");
    
      Thread thread3 = new Thread(()->{
          System.out.println("thread3 start");
          try {
              Thread.sleep(1000);
              thread2.join();
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
          System.out.println("thread3");
          System.out.println("thread3 end");
      },"3");
    
      System.out.println("thread will start");
      thread1.start();
      thread2.start();
      thread3.start();
      try {
          thread3.join();
      } catch (InterruptedException e) {
          e.printStackTrace();
      }
      System.out.println("thread did start end");
    }
    
    打印:
    thread will start
    thread will start
    thread1 start
    thread2 start
    thread3 start
    thread1
    thread1 end
    thread2
    thread2 end
    thread3
    thread3 end
    thread did start end
    
  • sleep():睡眠
  • wait():睡眠,其他线程会加入,与synchronized结合使用
  • notify():唤醒当前睡眠线程,与synchronized结合使用
  • notifyAll():唤醒所有睡眠线程
    thread1启动后waitthread2唤醒thread1
     public class CusThread01 {
      
      private static String lock = "lock";
      
      public static void main(String[] args) {
          Thread thread1 = new Thread(()->{
              synchronized (lock) {
                  System.out.println("thread1 start");
                  try {
                      Thread.sleep(1000);
                      lock.wait();
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
                  System.out.println("thread1 end");
              }
          },"1");
          thread1.start();
    
          new Thread(()->{
              synchronized(lock){
                  System.out.println("thread2 start");
                  try {
                      Thread.sleep(2000);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
                  lock.notifyAll();
                  System.out.println("thread2 end");
              }
          },"2").start();
      }
    }
    
    打印:
    thread1 start
    thread2 start
    thread2 end
    thread1 end
    

2. Runnable

public static void main(String[] args) {
    CusRunnable cusRunnable = new CusRunnable();
    Thread thread = new Thread(cusRunnable);
    thread.start();
}
public static class CusRunnable implements Runnable{
    @Override
    public void run() {
        System.out.println("CusRunnable run ");
    }
}

3. Callable

public static void main(String[] args) {
    CusCallable cusCallable = new CusCallable();
    FutureTask<String> futureTask = new FutureTask<>(cusCallable);
    Thread t = new Thread(futureTask);
    t.start();
    try {
        String res = futureTask.get();
        System.out.println("CusCallable res: " + res);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    }
}

public static class CusCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        return "CusThread.call run";
    }
}

4. 匿名内部类

new Thread(){
    @Override
    public void run() {
        System.out.println("1111");
    }
}.start();

new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("2222");
    }
}).start();

5. Lambda

new Thread(()-> System.out.println("111")).start();

6. 定时器

Timer timer = new Timer();
//每隔1s执行一次
timer.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        System.out.println("123445");
    }
},0/**延迟*/,1000/**间隔*/);

7. 线程池

ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(new Runnable() {
    @Override
    public void run() {
        System.out.println("1234");
    }
});

executorService.execute(()->{
    System.out.println("4321");
});
image.png

线程池

 public ThreadPoolExecutor(int corePoolSize, //核心线程池大小
                              int maximumPoolSize,  // 最大线程池大小
                              long keepAliveTime,  // 线程最大空闲时间
                              TimeUnit unit,  // 时间单位
                              BlockingQueue<Runnable> workQueue, // 线程等待队列
                              ThreadFactory threadFactory,  // 线程创建工厂
                              RejectedExecutionHandler handler ) { //拒绝策略
  • 拒绝策略:
    AbortPolicy:默认策略,抛出RejectedExecutionException异常
    CallerRunsPolicy:这提供了一个简单的反馈控制机制,可以减慢提交新任务的速度;
    DiscardPolicy:直接丢弃新提交的任务;
    DiscardOldestPolicy:如果执行器没有关闭,队列头的任务将会被丢弃,然后执行器重新尝试执行任务(如果失败,则重复这一过程);

  • 预定义线程池 FixedThreadPool

    public static ExecutorService newFixedThreadPool(int nThreads) {
          return new ThreadPoolExecutor(nThreads, nThreads,
                                        0L, TimeUnit.MILLISECONDS,
                                        new LinkedBlockingQueue<Runnable>());
      }
    

    corePoolSize=maximumPoolSize,线程都是核心线程,是一个固定大小的线程池
    keepAliveTime对核心线程无效,FixedThreadPool中全部都是核心线程
    workQueueLinkedBlockingQueue无界阻塞队列,队列最大值为Integer.MAX_VALUE,所以任务添加>消耗,可能会内存溢出。
    FixedThreadPool执行是无序的
    用途:用于web服务瞬时削峰,不会长时间高峰运行。

  • 直接握手队列CachedThreadPool

public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

corePoolSize =0,maximumPoolSize=Integer.MAX_VALUE,线程无限制
KeepAliveTime=60s,线程空闲时间为60s
workQueueSynchronousQueue同步队列SynchronousQueue不会有队列等待
用途:快速处理大量耗时短的任务,如:Netty的NIO接受请求

  • 单线程处理SingleThreadExecutor
    public static ExecutorService newSingleThreadExecutor() {
          return new FinalizableDelegatedExecutorService
              (new ThreadPoolExecutor(1, 1,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>()));
      }
    

Executors.newFixedThreadPool(1)这种单线程可以修改其corePoolSize,使其非单线程

  • 周期性调用ScheduledThreadPool

    public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
          return new ScheduledThreadPoolExecutor(corePoolSize);
      }
    

    ScheduledthreadPool extend ThreadPoolExecutor
    与Timer对比

    1. Timer 单线程 任务之间互相影响 绝对时间 单任务异常,后续任务受影响
    2. ScheduledThreadPoolExecutor 多线程 任务之间互不影响 相对时间 无影响
     // 特定时间延时后执行一次Runnable
      public ScheduledFuture<?> schedule(Runnable command,
                                         long delay, TimeUnit unit);
      // 特定时间延时后执行一次Callable
      public <V> ScheduledFuture<V> schedule(Callable<V> callable,
                                             long delay, TimeUnit unit);
      // 固定周期执行任务(与任务执行时间无关,周期是固定的)
      public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
                                                    long initialDelay,
                                                    long period,
                                                    TimeUnit unit);
       // 固定延时执行任务(与任务执行时间有关,延时从上一次任务完成后开始)
      public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
                                                       long initialDelay,
                                                       long delay,
                                                       TimeUnit unit);
    
  • 关闭线程池

    1. 当线程池执行shutdown时再调用线程池方法会执行拒绝策略
     public static void main(String[] args) {
      ThreadPoolExecutor executor = new ThreadPoolExecutor(4, 4, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
      executor.execute(() -> System.out.println("before shutdown"));
      executor.shutdown();
      executor.execute(() -> System.out.println("after shutdown"));
    }
    
    1. 等待队列中有100个任务,执行task0后立即shutdown,并不会停止接下来的100个任务
    public class WaitqueueTest {
    public static void main(String[] args) {
        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
        for(int i = 1; i <= 100 ; i++){
            workQueue.add(new Task(String.valueOf(i)));
        }
        ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 10, TimeUnit.SECONDS, workQueue);
        executor.execute(new Task("0"));
        executor.shutdown();
        System.out.println("workQueue size = " + workQueue.size() + " after shutdown");
    }
    
    static class Task implements Runnable{
        String name;
        
        public Task(String name) {
            this.name = name;
        }
        
        @Override
        public void run() {
            for(int i = 1; i <= 10; i++){
                System.out.println("task " + name + " is running");
            }
            System.out.println("task " + name + " is over");
        }
    }
    }
    
    1. 队列中有100个任务,执行task0立即shutdownNow,task0执行完毕,其他的停止
    public class WaitqueueTest {
    public static void main(String[] args) {
        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
        for(int i = 1; i <= 100 ; i++){
            workQueue.add(new Task(String.valueOf(i)));
        }
        ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 10, TimeUnit.SECONDS, workQueue);
        executor.execute(new Task("0"));
        // shutdownNow有返回值,返回被抛弃的任务list
        List<Runnable> dropList = executor.shutdownNow();
        System.out.println("workQueue size = " + workQueue.size() + " after shutdown");
        System.out.println("dropList size = " + dropList.size());
    }
    
    static class Task implements Runnable{
        String name;
        
        public Task(String name) {
            this.name = name;
        }
        
        @Override
        public void run() {
            for(int i = 1; i <= 10; i++){
                System.out.println("task " + name + " is running");
            }
            System.out.println("task " + name + " is over");
        }
    }
    }
    
    1. 通过interrupt来停止线程
    public static void main(String[] args) throws InterruptedException {
      ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
      executor.execute(new Task("0"));
      Thread.sleep(1);
      executor.shutdownNow();
      System.out.println("executor has been shutdown");
    }
    
    static class Task implements Runnable {
      String name;
      public Task(String name) {
        this.name = name;
    }
    
    @Override
    public void run() {
    
        for (int i = 1; i <= 100 ; i++) {
            if (!Thread.currentThread().isInterrupted()){
                Thread.yield();
                System.out.println("task " + name + " is running, round " + i);
            }
            else {
                System.out.println("stop");
                break;
            }
        }
    
    }
    }
    

相关文章

  • Android

    线程间通信 主线程和工作线程主线程和工作线程 工作线程与工作线程工作线程与工作线程 为什么主线程Looper.lo...

  • 三、操作系统之线程

    前言 什么是线程 引入线程的原因 线程的概念 线程和进程的关系 线程结构 线程有点 多线程模型 用户线程和内核线程...

  • Thread

    队列 线程锁 多线程,线程池 队列 多线程爬虫示例 多线程 自定义线程 线程池

  • 总结多线程与设计模式+synchronized+性能+高吞吐+死

    Java线程 Java语言的线程 何谓线程 线程启动 线程的暂时停止 线程的共享互斥 线程的协调 线程的状态转移 ...

  • 多线程编程

    摘要 线程概念,线程与进程的区别与联系学会线程控制,线程创建,线程终止,线程等待了解线程分离与线程安全学会线程同步...

  • java线程池

    线程VS线程池 普通线程使用 创建线程池 执行任务 执行完毕,释放线程对象 线程池 创建线程池 拿线程池线程去执行...

  • java并发之守护线程

    java中有两种线程,用户线程和守护线程用户线程:主线程停止时,用户线程不会停止守护线程:主线程停止时,守护线程也...

  • Java线程池的使用

    线程类型: 固定线程 cached线程 定时线程 固定线程池使用 cache线程池使用 定时调度线程池使用

  • 线程基础知识

    线程学习 线程的基础知识 线程是什么? 线程和进程的关系 线程的6个状态 线程优先级 主线程、多线程、后台线程的概...

  • 多线程介绍

    一、进程与线程 进程介绍 线程介绍 线程的串行 二、多线程 多线程介绍 多线程原理 多线程的优缺点 多线程优点: ...

网友评论

      本文标题:线程

      本文链接:https://www.haomeiwen.com/subject/vvhslrtx.html