Java多线程优化方法及使用方式

  

  

在编程中,我们不可逃避的会遇到多线程的编程问题,因为在大多数的业务系统中需要并发处理,如果是在并发的场景中,多线程就非常重要了。另外,我们在面试的时候,面试官通常也会问到我们关于多线程的问题,如:如何创建一个线程?我们通常会这么回答,主要有两种方法,第一种:继承线程类,重写运行方法;第二种:实现运行的接口,重写运行方法。那么面试官一定会问这两种方法各自的优缺点在哪,不管怎么样,我们会得出一个结论,那就是使用方式二,因为面向对象提倡少继承,尽量多用组合。

  

这个时候,我们还可能想的到,如果想得到多线程的返回值怎么办呢?根据我们多学到的知识,我们会想到实现可调用的接口,重写调用方法。那么多线程到底在实际项目中怎么使用呢,他有多少种方式呢?

  

首先,我们来看一个例子:

  

癑ava多线程优化方法及使用方式”,

  

这是一种创建多线程的简单方法,很容易理解,在例子中,根据不同的业务场景,我们可以在线程()里边传入不同的参数实现不同的业务逻辑,但是,这个方法创建多线程暴漏出来的问题就是反复创建线程,而且创建线程后还得销毁,如果对并发场景要求低的情况下,这种方式貌似也可以,但是高并发的场景中,这种方式就不行了,因为创建线程销毁线程是非常耗资源的,所以根据经验,正确的做法是我们使用线程池技术,JDK提供了多种线程池类型供我们选择,具体方式可以查阅JDK的文档。

  

癑ava多线程优化方法及使用方式”,

  

这里代码我们需要注意的是,传入的参数代表我们配置的线程数,是不是越多越好呢?肯定不是,因为我们在配置线程数的时候要充分考虑服务器的性能,线程配置的多,服务器的性能未必就优。通常,机器完成的计算是由线程数决定的,当线程数到达峰值,就无法在进行计算了。如果是耗CPU的业务逻辑(计算较多),线程数和核数一样就到达峰值了,如果是耗I/O的业务逻辑(操作数据库,文件上,传下载等),线程数越多一定意义上有助于提升性能。

  

线程数大小的设定又一个公式决定:

  

Y=N * ((a + b)/a),其中,N: CPU核数,答:线程执行时程序的计算时间,b:线程执行时,程序的阻塞时间。有了这个公式后,线程池的线程数配置就会有约束了,我们可以根据机器的实际情况灵活配置。

  

  

最近的项目中用到了所线程技术,在使用过程中遇到了很多的麻烦,趁着热度,整理一下几种多线程框架的性能比较。目前所掌握的大致分三种,第一种:ThreadPool(线程池)+ CountDownLatch(程序计数器),第二种:Fork/Join框架,第三种JDK8并行流、下面对这几种方式的多线程处理性能做一下比较总结。

  

首先,假设一种业务场景,在内存中生成多个文件对象,这里暂定30000年,(thread . sleep(时间))线程睡眠模拟业务处理业务逻辑,来比较这几种方式的多线程处理性能。

  

<强> 1)单线程

  

这种方式非常简单,但是程序在处理的过程中非常的耗时,使用的时间会很长,因为每个线程都在等待当前线程执行完才会执行,和多线程没有多少关系,所以效率非常低。

  

首先创建文件对象,代码如下:

        公开课FileInfo {   私人文件名字符串;//文件名   私人字符串文件类型;//文件类型   私人字符串文件大小;//文件大小   私人字符串fileMD5;//MD5码   私人字符串fileVersionNO;//文件版本号   公共FileInfo () {   超级();   }   公共FileInfo(琴弦文件名、文件类型、文件大小的字符串,字符串fileMD5,字符串fileVersionNO) {   超级();   这一点。文件名=文件名;   这一点。fileType=文件;   这一点。文件大?文件大小;   这一点。fileMD5=fileMD5;   这一点。fileVersionNO=fileVersionNO;   }   公共字符串getFileName () {   返回文件名;   }   公共空间setFileName(字符串文件名){   这一点。文件名=文件名;   }   公共字符串getFileType () {   返回文件类型;   }   公共空间setFileType(字符串文件类型){   这一点。fileType=文件;   }   公共字符串getFileSize () {   返回文件大小;   }   公共空间setFileSize(字符串文件大小){   这一点。文件大?文件大小;   }   公共字符串getFileMD5 () {   返回fileMD5;   }   公共空间setFileMD5(字符串fileMD5) {   这一点。fileMD5=fileMD5;   }   公共字符串getFileVersionNO () {   返回fileVersionNO;   }   公共空间setFileVersionNO(字符串fileVersionNO) {   这一点。fileVersionNO=fileVersionNO;   }

Java多线程优化方法及使用方式