Java多线程应用(1)

目标:掌握多线程的使用及应用场景

  • 怎么使用多线程

    // 尽量不要如此使用
    new Thread(new Runnable() {
           @Override
           public void run() {
    
           }
    }).start();
    // 通过线程池方便管理
    Executor executor = Executors.newCachedThreadPool();
    executor.execute(runnable);
    
  • 进程和线程的区别

    其实没有可比性,之所以大家喜欢用来比较是因为他们都可以并行,两个进程可以并行,两个线程也可以并行,所以大家喜欢用来对比。

    但其实差别还是比较大的,进程在操作系统中是拥有独立空间的,并且进程间是不共享的,而一个进程中可能会包含很多个线程,而线程间是可以共享资源。

  • CPU线程与操作系统的线程怎么理解

    CPU线程就是我们平时听到的几核CPU的概念,比如6核的CPU,它的CPU线程就是6,它表示CPU同时只能干六件事,而我们代码中所开的线程其实是操作系统的线程,操作系统通过时间分片可以将线程开的很多很多。

  • ThreadPoolExecutor

    以ThreadPoolExecutor为例,他的构造函数里面会有几个重要的参数:

  • 第一个参数corePoolSize表示该线程池需要保留的线程数量,即使在空闲的时候。

    maximumPoolSize表示当前线程池最大可以拥有多少个线程,当线程池中开到最大,并且所有线程都在执行任务,此时如果有任务来了,就需要等待线程池中有空闲的线程释放出来。

    keepAliveTime表示当线程池中超过corePoolSize的部分,在空闲状态时可以继续保留的时间,一旦超过这个时间就会销毁。

    timeUnit表示上面参数的时间单位

    workQueue显然就是线程池正在满池运行,新的待执行任务需要放在这个队列里等待空闲线程的到来。

  • newFixedThreadPool(int nThreads)

    这个方法是用来创在保持特定数量的线程池,因为这个数量是既是线程池的最大线程数,也是线程池需要保留的线程数,所以,线程也不好增加,在空闲状态时也不能回收多余的。

    所以它的应用场景也是比较少的,一般是用来集中处理一些爆发性的事物后立即释放,比如突然来了20张图片要处理,这个时候肯定不能一张一张的处理,可以开多线程并行处理,如下所示:

    List<Bitmap> imgs = somewhereGetImgs(20);
    ExecutorService executor = Executors.newFixedThreadPool(20);
    for(Bitmap bitmap: imgs) {
    	// 向线程池中扔了20个任务同时执行
    	executor.execute(processImgRunnable);
    }
    // 执行完就快速的回收
    executor.shutdown();
    
  • Callable

    有返回值的Runnable。

    举个例子:

  • 既然要放到异步线程里去执行,那返回结果又有什么意义呢,难道要阻塞主线程一直等任务线程执行完?

    上面的例子就说明了部分使用场景,我们可以先拿到一个future的实例来在后面进行判断是否任务执行完了(当然,不一定是上面死循环的方式),实际可以根据具体业务来做。

猜你喜欢

转载自blog.csdn.net/codeyanbao/article/details/116355306