线程和线程池

一:简单回顾

1.java中线程的使用

方式1:继承Thread类

(1)实例

public class MyThread1 extends Thread{
    String sign = "This is MyThread1";

    @Override
    public void run(){
        for (int i = 0;i<20;i++){
            System.err.println(sign+"->"+i);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

方式2:继承Runnable接口

(2)实例

public class MyThread2 implements Runnable {
    String myThread2 = "MyThread2";
    @Override
    public void run() {
        for (int i = 0;i < 25;i++){
            System.err.println(myThread2+"->"+i);
            try {
                Thread.sleep(120);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

启动以上线程测试:

(3)实例

public class Main {

    public static void main(String[] args) throws InterruptedException {
        long startTimeMillis = System.currentTimeMillis();
        // 通过实现Runnable接口
        MyThread2 myThread2 = new MyThread2();
        Thread threadByRunnable = new Thread(myThread2);
        // 启动线程
        threadByRunnable.start();
        // 继承Thread类
        MyThread1 myThread1 = new MyThread1();
        // 启动线程
        myThread1.start();
        /* 注意这里不是调运run()方法,而是调运线程类Thread的start方法,在Thread方法内部,会调运本地系统方法,最终会自动调               * 运自己线程类的run方法
        */
        // 主线程休眠100ms
        Thread.sleep(100);
        System.out.println("主线程结束!用时:" + (System.currentTimeMillis() - startTimeMillis));
    }
}

运行结果每次都不会相同,这里展示运行结果:

MyThread2->0
This is MyThread1->0
This is MyThread1->1
主线程结束!用时:103
MyThread2->1
This is MyThread1->2
MyThread2->2
This is MyThread1->3
MyThread2->3
This is MyThread1->4
MyThread2->4
This is MyThread1->5
This is MyThread1->6
MyThread2->5
This is MyThread1->7
MyThread2->6
This is MyThread1->8
MyThread2->7
This is MyThread1->9
MyThread2->8
This is MyThread1->10
MyThread2->9
This is MyThread1->11
MyThread2->10
This is MyThread1->12
This is MyThread1->13
MyThread2->11
This is MyThread1->14
MyThread2->12
This is MyThread1->15
MyThread2->13
This is MyThread1->16
MyThread2->14
This is MyThread1->17
MyThread2->15
This is MyThread1->18
This is MyThread1->19
MyThread2->16
MyThread2->17
MyThread2->18
MyThread2->19
MyThread2->20
MyThread2->21
MyThread2->22
MyThread2->23
MyThread2->24

建议:尽量使用Runnable方式实现线程,防止Java单继承的考虑,Runnable面向接口,更容易拓展

二:线程池

(1)为什么使用线程池?

1.降低资源的消耗。主要是降低创建和销毁线程时产生的CPU消耗,线程池通过持续工作的线程执行不断分配的任务,减少线程的创建和销毁。

2.提高响应速度。

3.提高线程的可管理性,线程是稀缺资源,频繁的创建销毁,以及没有控制的大量创建,都会影响系统的稳定性。使用线程池可以统一分配,调优,监控资源。

引用:https://yq.aliyun.com/articles/221709

(2)线程池种类

 常见的四种线程池分别为newCachedThreadPool、newFixedThreadPool、newSingleThreadExecutor、newScheduleThreadPool。

四种线程池本质上也是ThreadPoolExecutor,只是这些参数都是固定好了的,我们可以直接使用

newCachedThreadPool:

/**
 * Creates a thread pool that creates new threads as needed, but
 * will reuse previously constructed threads when they are
 * available, and uses the provided
 * ThreadFactory to create new threads when needed.
 * @param threadFactory the factory to use when creating new threads
 * @return the newly created thread pool
 * @throws NullPointerException if threadFactory is null
 */
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>(),
                                  threadFactory);
}

(1)创建一个可缓存的线程池,如果线程长度超过处理需要,可灵活回收空闲线程,若无可回收线程,创建线程。

(2)工作线程创建数量几乎不受限制(最大数目为Integer.MAX_VALUE),可灵活向线程池中添加线程。

(3)若长时间未向线程池提交任务,如果指定空闲线程时间(默认1分钟),则该工作线程终止。终止后,若新提交任务,线程池重新创建一个工作线程。

(4)在使用newCatchThreadPool,需要控制线程的数量,否则,若大量线程同时运行,造成系统瘫痪。

适合于耗时短,不需要考虑同步的场合。

newFixedThreadPool:

/**
 * Creates a thread pool that reuses a fixed number of threads
 * operating off a shared unbounded queue, using the provided
 * ThreadFactory to create new threads when needed.  At any point,
 * at most {@code nThreads} threads will be active processing
 * tasks.  If additional tasks are submitted when all threads are
 * active, they will wait in the queue until a thread is
 * available.  If any thread terminates due to a failure during
 * execution prior to shutdown, a new one will take its place if
 * needed to execute subsequent tasks.  The threads in the pool will
 * exist until it is explicitly {@link ExecutorService#shutdown
 * shutdown}.
 *
 * @param nThreads the number of threads in the pool
 * @param threadFactory the factory to use when creating new threads
 * @return the newly created thread pool
 * @throws NullPointerException if threadFactory is null
 * @throws IllegalArgumentException if {@code nThreads <= 0}
 */
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>(),
                                  threadFactory);
}

(1)创建一个指定工作线程数量的线程池,每提交一个任务,创建一个线程,如果工作线程数量达到线程初始化的最大数,将提交的任务存储到线程池指定的工作队列中。

(2)newFixedThreadPool可以提高线程池的效率和节省创建线程时所消耗的开销

(3)在线程空闲时,即线程池中无执行任务时,不会释放工作线程,占用一定的系统资源。

符合常用场合

newSingleThreadExecutor:

 

/**
 * Creates an Executor that uses a single worker thread operating
 * off an unbounded queue, and uses the provided ThreadFactory to
 * create a new thread when needed. Unlike the otherwise
 * equivalent {@code newFixedThreadPool(1, threadFactory)} the
 * returned executor is guaranteed not to be reconfigurable to use
 * additional threads.
 *
 * @param threadFactory the factory to use when creating new
 * threads
 *
 * @return the newly created single-threaded Executor
 * @throws NullPointerException if threadFactory is null
 */
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>(),
                                threadFactory));
}

(1)一个单线程线程池,只有一个线程在工作(若该线程因异常终结,一个新的线程代替),能够保证所有的任务的执行顺序按照提交顺序执行,同一个时段只有一个任务执行。

适用需保证任务执行顺序场景

newScheduleThreadPool:

 

/**
 * Creates a thread pool that can schedule commands to run after a
 * given delay, or to execute periodically.
 * @param corePoolSize the number of threads to keep in the pool,
 * even if they are idle
 * @return a newly created scheduled thread pool
 * @throws IllegalArgumentException if {@code corePoolSize < 0}
 */
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
    return new ScheduledThreadPoolExecutor(corePoolSize);
}

(1)创建一个定长的线程池,而且支持定时的以及周期性的任务执行。
(2)可定时运行(初始延时),运行频率(每隔多长时间运行,还是运行成功一次之后再隔多长时间再运行)的线程池
适合定时以及周期性执行任务的场合。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值