Java并发(三):实例引出并发应用场景

前两篇介绍了一些Java并发的基础知识,博主正巧遇到一种需求:查询数据库,根据查询结果集修改数据库记录,但整个流程是作成了一个schedule的,而且查询比较耗时,而且须要每两分钟执行一次,cpu常常因等待服务器响应的查询结果而进入等待,故须要在此基础上考虑性能优化,sql优化能够提升一些系统效率,一样,多线程也能够...html

下面博主作个DEMO引出一些Java并发的实际应用场景:java

 

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;


public class TestThread implements Runnable{

    private String name;

    private Integer i = 0;

    List list = new ArrayList();

    public TestThread(String name) {
        this.name=name;
        for(int i=0; i<100; i++){
            list.add(i);
        }
    }

    @Override
    public void run() {
        Long past = System.currentTimeMillis();
        get();
        System.out.println(System.currentTimeMillis()-past);
    }
    private void get(){

        while(true){
            try{
                Thread.sleep(200);
            }catch(Exception e){
                e.printStackTrace();
            }
            synchronized (i){
                if(i>=100){
                    break;
                }
                System.out.println(list.get(i++));
            }

        }

    }

    public static void main(String[] args) {
        //线程池方式
        ExecutorService exector = new ThreadPoolExecutor(5, 7, 30,
                TimeUnit.MINUTES, new ArrayBlockingQueue<>(10));
        //对于最大线程数和核心线程数的参考值,对于cpu密集型任务,能够选择NCPU+1,对于耗时较长的IO操做,能够选择2*NCPU
        TestThread a = new TestThread("A");
        exector.execute(a);
        exector.execute(a);
        exector.execute(a);
        exector.execute(a);
        exector.execute(a);
        exector.execute(a);
        exector.execute(a);
        exector.execute(a);

        //普通方式
        /*TestThread a = new TestThread("A");
        new Thread(a).start();
        new Thread(a).start();
        new Thread(a).start();
        new Thread(a).start();*/
    }
}

TIP:不推荐使用Executors.newFixedThreadPool()来建立线程池,你们看底层代码:sql

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

newFixedThreadPool()方法底层仍是调用了new ThreadPoolExecutor(),但线程等待队列(LinkedBlockingQueue)默认是不限定其长度的,意味着有大量线程入队时,会有内存溢出的风险,推荐你们使用new ThreadPoolExecutor()来建立线程池...数据库

 

经过以上代码(能够跑)感觉获得单线程和多线程的性能差距,设备越好,cpu核数越多,应该结果越明显,固然这不是绝对的,有时咱们得考虑多线程的上下文切换的时间占用率和多线程同步的性能消耗...另外,咱们日常应该使用线程池来管理线程,由于比较方便,JavaAPI也已经将细节实现到位,各位能够用这样线程安全的方式结合索引遍历集合,这样对于集合内的元素就能够多线程遍历并触发各自的操做,例如更新数据库等,能够说很是实用...安全

 

多线程使用的主要目的在于:

一、吞吐量:你作WEB,容器帮你作了多线程,可是他只能帮你作请求层面的。简单的说,可能就是一个请求一个线程。或多个请求一个线程。若是是单线程,那同时只能处理一个用户的请求。

二、伸缩性:也就是说,你能够经过增长CPU核数来提高性能。若是是单线程,那程序执行到死也就利用了单核,确定没办法经过增长CPU核数来提高性能。
性能优化

 

参考博文:http://www.cnblogs.com/dolphin0520/p/3932921.html服务器

相关文章
相关标签/搜索