欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

【多线程】多线程执行就一定效率更快吗?

程序员文章站 2022-04-12 22:38:28
多线程执行就一定效率更快吗?显然不是的。1. 上下文切换一个线程在执行的过程中然后记录一下这个线程当前的状态突然间停止,然后切换到下一个线程执行,这个现象就叫做上下文切换。比如说我在看书的时候突然遇到一个英文单词不认得了,然后记录这本书看到了多少页了,再拿起英文翻译书查查这个单词的意思。2.示例代码public class ConcurrencyTest { private static final long count=10000L; public static void m...

多线程执行就一定效率更快吗?显然不是的。

1. 上下文切换

一个线程在执行的过程中然后记录一下这个线程当前的状态突然间停止,然后切换到下一个线程执行,这个现象就叫做上下文切换。比如说我在看书的时候突然遇到一个英文单词不认得了,然后记录这本书看到了多少页了,再拿起英文翻译书查查这个单词的意思。

2.示例代码

public class ConcurrencyTest {

    private  static final long count=10000L;

    public static void main(String[] args) throws InterruptedException {

            concuttency();
            serial();
    }


    /**
     * 多线程执行
     * @throws InterruptedException
     */
    private  static void concuttency() 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+",a="+a);
    }

试着运行上边的代码并将count的数值一次改为:1万、10万、100万、1000万、1亿 就会发现随着数值的增大多线程环境执行时间比单线程就快了。
为什么数值小的时候多线程就执行慢呢?
很明显上下文切换期间的会有时间间隔导致的。

3.怎样减少上下文切换

(1)无锁并发编程。比如可以利用hash取模的方式让不同的id在不同的线程上执行。

(2)cas算法。java中的atomic包中使用的cas算法来更新数据,不需要加锁。

(3)使用最少的线程。避免创建了多余的线程。

4.死锁

比如:有两个资源A和B ,有两个线程。当执行线程1的时候锁住了A资源,运行获取到B资源的时候这个时候,线程2把B资源锁住的,这个时候线程1等待B资源释放,反之依然。这种现象叫做线程死锁。

5.避免死锁

(1)避免一个线程使用多个锁。

(2)避免一个线程占用多个资源,尽量保证每个锁只占用一个资源。

(3)尝试使用定时锁,使用lock.tryLock(timeout)来代替使用内部锁机制。

(4)数据库锁,加锁和解锁在一个数据库连接里。

本文地址:https://blog.csdn.net/qq_36649893/article/details/109609824

相关标签: 多线程