初识并发编程

并发编程的目的是 程序运行得更快,但是,并不是启 更多的 线 程就能 程序最大限度地并发执 行。在 行并 发编 ,如果希望通 线 行任 务让 程序运行得更快,会面临 非常多的挑 ,比如上下文切 问题 、死 问题 ,以及受限于硬件和 件的 源限制问题

目录

上下文切换

多线程一定快吗?

什么情况下适合使用多线程呢?

如何减少上下文的切换

上下文切换

即使是 理器也支持多 线 行代 CPU 过给 每个 线 程分配 CPU 时间 片来 实现这个机制。 时间 片是 CPU 分配 各个 线 程的 时间 ,因 为时间 片非常短,所以 CPU 不停地切换线程 行, 多个 线 程是同 时执 行的, 时间 片一般是几十毫秒。
CPU 过时间 片分配算法来循 环执 行任 ,当前任 务执 行一个 时间 片后会切 到下一个任务 。但是,在切 前会保存上一个任 的状 ,以便下次切 个任 务时 ,可以再加 载这个任务 的状 。所以任 从保存到再加 程就是一次上下文切
可见切换上下文是会影响线程的执行速度的。同时也引发了我们的下一个问题。

多线程一定快吗?

先给出一段代码,说一说你的看法
public class ConcurrencyTest {
    private static final long count = 10000l;
    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+",a="+a);
    }
}

首先答案肯定是“不一定”的,比如下面给出我执行的结果

这里的单线程就比上面的多线程要快,但是你多执行几次就肯定会发现其他的情况。

这样的结果也佐证了上述问题的答案是“不一定”的,要看具体情况而言。也进而抛出了我们的下一个问题。

什么情况下适合使用多线程呢?

首先我们要先知道,多线程为什么有时候会比单线程慢,这是因为线程有创建和上下文切换的开销,这段时间cpu啥么也不会做,只在那里“等”,所以在cpu产生浪费比例大的时候可以使用多线程来。通过上下文切换和cpu的浪费比例来决定我们要使用的线程数。

如何减少上下文的切换

减少上下文切 的方法有无 发编 程、 CAS 算法、使用最少 线 程和使用 程。
  • 发编程。多线锁时,会引起上下文切,所以多线理数据,可以用一
  • 法来避免使用,如将数据的ID按照Hash算法取模分段,不同的线理不同段的数据。
  • CAS算法。JavaAtomic包使用CAS算法来更新数据,而不需要加
  • 使用最少线程。避免建不需要的线程,比如任很少,但是建了很多线程来理,这样会造成大量线程都于等待状
  • 程:在单线程里实现多任度,并在单线程里持多个任务间的切
  • 10
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值