上下文切换与死锁

2019-01-01  本文已影响8人  黑小鹰

多线程一定快吗?


答案是不一定。当并发执行的累积数量一定以内,并行会比串行执行要慢,此处用的测试用例是累加,那么为什么会出现这种情况呢?

这是因为线程的创建的上下文切换的开销

上下文切换

单核处理器也支持多线程执行代码,CPU通过给每个线程分配CPU时间片来实现这个机制,因为时间片非常短,所以CPU通过不停切换线程执行的,时间一般是即使毫秒(ms)


public class ConcurrencyTest {
    private  static final  long count = 100001;
    
    public static void main(String[] args) throws InterruptedException{
        concurrency();
        serial();
    }

    private static void concurrency() throws InterruptedException {
        long start = System.currentTimeMillis();
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                int a = 0;
                for(long i = 0;i<count;i++) {
                    a += 5;
                }
            }
            
        });
        thread.start();
        int b = 0;
        for(long i = 0;i<count;i++) {
            b--;
        }
        long time = System.currentTimeMillis()-start;
        thread.join();
        System.out.println("concurrency:"+time+"ms,"+" b="+b);
    }

    private static void serial() {
        long start = System.currentTimeMillis();
        int a = 0;
        for(long i =0;i<count;i++) {
            a +=5;
        }
        int b = 0;
        for(long i =0;i<count;i++) {
            b--;
        }
        long time = System.currentTimeMillis() - start;
        System.out.println("serial:"+time+"ms,"+" b="+b);
    }
}

这就像我们同时读两本书,当我们在读一本英文的技术书时,发现某个单词不认识,于是便打开中英文字典,但是在放下英文技术书之前,大脑必须先记住这本书读到了多少页的第多少行,等查完单词之后,能够继续读这本书。这样的切换是会影响读书效率的,同样上下文切换也会影响多线程的执行速度

如何减少上下文切换呢?

无锁并发编程 使用一下办法来避免使用锁
CAS算法 Compare And Swap 即比较和替换
使用最小线程数

死锁列子

package com.hunau;

public class DeadLockDemo {
    
    private static String  A = "A";

    private static String  B = "B";
    
    public static void main(String[] args) {
        new DeadLockDemo().deadLock();
    }

    private void deadLock() {
        Thread t1 = new Thread(new Runnable() {

            @Override
            public void run() {
                synchronized(A) {
                    try {
                        Thread.currentThread().sleep(2000);
                    }catch(InterruptedException e) {
                        e.printStackTrace();
                    }
                    
                    synchronized(B) {
                        System.out.println("1");
                    }
                }
                
            }
            
        });
        
        Thread t2 = new Thread(new Runnable() {

            @Override
            public void run() {
                synchronized(B) {
                    synchronized(A) {
                        System.out.println("2");
                    }
                }
                
            }
            
        }) ;
        t1.start();
        t2.start();
    }
}

上一篇 下一篇

猜你喜欢

热点阅读