• 《Java程序性能优化》之并发优化


    第四章 并行程序优化

    1.非阻塞同步避免了基于锁的同步的缺陷,无锁算法没有锁竞争带来的系统开销,也没有线程间频繁调度带来的开销。
    CAS算法:包含3个参数CAS(v,e,n)。V表示要更新的变量,E表示预期值,N表示新值
    2.JDK的java.util.concurrent.atomic包下,有一组使用无锁算法实现的原子操作类,如AtomicInteger/AtomicIntegerArray/AtomicLongArray等,

    分别包装了对整数、整数数组、长整形数组等的多线程安全操作。

    如:

    public class AtomicTest {
    
        public static final int MAX_THREADS=3; 
        public static final int TASK_COUNT=3; 
        public static final int TARGET_COUNT=10000; 
        private AtomicInteger account=new AtomicInteger(0);//无锁的原子操作数量
        private int  count=0;
        
        //有锁的加法
        private synchronized int add() {
            return count++;
        }
        
        //有锁的操作
        private synchronized int getCount() {
            return count;
        }
        
        //实现有锁操作的内部类
        public class SynchThread implements Runnable{
            
            protected String name;
            protected long starttime;
            AtomicTest out;
            public  SynchThread(AtomicTest o,long starttime) {
                out=o;
                this.starttime=starttime;
            }
    
            @Override
            public void run() {
                int v=out.add();//有锁的加法
                while (v<TARGET_COUNT) {
                    v=out.add();//达到目标值前,不停的循环
                }
                long endtime=System.currentTimeMillis();//系统当前时间 精确到ms
                System.out.println("SynchThread spend:"+(endtime-starttime)+"ms");
            }
        }
        //实现原子操作的内部类
        public class AtomicThread implements Runnable{
            
            protected long starttime;
            
            public AtomicThread(long starttime){
                this.starttime=starttime;
            }
            
            @Override
            public void run() {
                int v=account.incrementAndGet();
                while(v<TARGET_COUNT){
                    v=account.incrementAndGet();
                }
                long endtime=System.currentTimeMillis();
                System.out.println("AtomicThread spend:"+(endtime-starttime)+"ms");
            }    
        }
        
        /**
         * JUnit方法测试
         * @throws InterruptedException
         */
        @Test
        public void testAtomic() throws InterruptedException {
            ExecutorService exe=Executors.newFixedThreadPool(MAX_THREADS);//初始化三个线程
            long starttime=System.currentTimeMillis();
            AtomicThread atomic=new AtomicThread(starttime);
            
            for(int i=0;i<TARGET_COUNT;i++){
                exe.submit(atomic);//提交三个线程开始工作
            }
            Thread.sleep(1000);//重新分配
        }
    
    //    @Test
        public void testSynch() throws InterruptedException {
            ExecutorService exe=Executors.newFixedThreadPool(MAX_THREADS);
            long starttime=System.currentTimeMillis();
            SynchThread synch=new SynchThread(this,starttime);
            
            for(int i=0;i<TARGET_COUNT;i++){
                exe.submit(synch);
            }
            Thread.sleep(1000);
            //检测线程池是否关闭
            System.out.println(exe.isTerminated());
            }
    }

    第五章 JVM调优

    1.JVM虚拟机将其内存数据分为程序计数器、虚拟机栈,本地方法栈,Java堆,和方法去等部分。

    2.Java虚拟机栈,在Java 虚拟机规范中,定义了两种异常与占空间相关,即StackOverError和OutOfMemoryError。如果线程在计算过程中,请求的栈深度大于最大可用的栈深度,则抛出SOE,如果Java栈可以动态扩展,而在扩展栈的过程中,没有足够的内存空间来支持栈的扩展,则抛出OutOfMemoryError。
    栈的大小直接决定了函数调用的可达深度。
    如:

    public class StackOverTest {
        private int count=0;
        public void recursion(){//没有出口的递归函数
            count ++;         //计数加一
            recursion();
        }
        
        @Test
        public void stest(){
            try{
                recursion();//递归调用
            }catch(Throwable t){
                //打印栈的深度
                System.out.println("the depth of stack is "+count);
                t.printStackTrace();
            }
        }
    }

     使用-Xss修改栈的大小后,函数调用深度明显上升。

     

  • 相关阅读:
    JAVA8 之 Stream 流(四)
    关于iphone 6s 页面功能不能正常使用问题
    关于ES6语法的 一些新的特性
    微信授权一直跳转
    js 一道题目引发的正则的学习
    关于this在不同使用情况表示的含义
    详细解析arry.map() ,function.apply() 方法
    关于服务器无法在已发送http表头之后设置状态问题
    七牛上传视频并转码
    使用 v-cloak 防止页面加载时出现 vuejs 的变量名
  • 原文地址:https://www.cnblogs.com/binyue/p/3913003.html
Copyright © 2020-2023  润新知