并发编程的几个挑战

并发编程的目的是为了让我们的程序变得更快,但是,并不是启动更多的线程就能让程序最大限度地并发执行。线程不在于多,在并发编程中,我们将面临如下挑战:上下文切换、死锁问题、受限于软硬件资源限制问题。

上下文切换

单核CPU是如果实现多线程的呢?

CPU通过给每个线程分配时间片来实现,时间片是分配给线程的时间。因为时间片非常短,所以CPU不停地切换线程执行,我们感觉上是同时执行的。(一般的,时间片只有十几毫秒 ms

当一个任务执行一个时间片之后,会切换成下一个任务执行,但是切换之前会保存这个任务的状态,以便下次回到这个任务的时候,可以下载上一次的状态,继续执行。这样,一个任务从保存到再加载的过程就是一次上下文切换。

上面给出了时间片上下文切换的解释。不只是计算机遵循这些原则。

拿现实生活中的例子,我们阅读英文书籍,遇到不会的单词,记住读到的位置,然后去查词典,查会了之后,我们回到上次卡住的位置继续阅读。想到回到原来的位置,大脑必须得记住在什么位置。这样周而复始,查单词和读书之间的切换是会影响读书效率的。这样也就不难理解,上下文切换对多线程的影响了。

多线程一定快吗?根据一个代码的实例,来探讨一下这个问题:

package com.cuteximi.concurrent;

/**
 * @program: Java-300
 * @description: 多线程一定快吗?
 * @author: TSL
 * @create: 2018-10-11 14:22
 **/
public class TestConcurrent {
    private static final long count = 10000;

    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 (int 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 的值。对比两种方式的执行速度。

count的值串行方法耗时(ms)并行方法耗时(ms)并行比串行快多少
1万01
10万34
100万66差不多
1000万1811
1亿16079快了一倍多

上表的数据是一个平均值,但是很容易看出多线程就不一定快!
那么一开始的时候为什么串行比并行还要快呢?是因为并行存在创建线程和上下文切换的花销。随着数量的扩大,多线程才显示出优势。

我们不得不重视,上下文切换的开销!

死锁

?是一个很有用的工具,使用锁的过程中最容易出现的就是死锁,一旦产生死锁就会造成系统不可用。看下面这段代码:

package com.cuteximi.concurrent;

/**
 * @program: Java-300
 * @description: 死锁的例子
 * @author: TSL
 * @create: 2018-10-11 15:14
 **/
public class DeadLockDemo {
    private static String A = "A";
    private static String B = "B";

    public static void main(String[] args) {
        deadLock();
    }
    private static void deadLock(){
        // 线程1
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (A){
                    try {
                        Thread.sleep(2000);
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                    synchronized (B){
                        System.out.println("111111");
                    }
                }
            }
        });

        // 线程2
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (B){
                    synchronized (A){
                        System.out.println("222222222");
                    }
                }
            }
        });

        t1.start();
        t2.start();
    }
}

执行这段代码的时候,一直结束不了,因为线程1 和线程2在互相等待。

如何避免死锁呢?

  • 避免一个线程同时获得多把锁。
  • 避免一个线程在?内同时获得多个资源。尽量保证每把锁仅占用一个资源。
  • 尝试使用定时锁,使用lock.tryLock(timeout)来代替内部锁。
  • 对于数据库锁,加锁和解锁必须在一个数据库连接里面,否则会出现解锁失败的情况。

资源限制

程序执行速度受限于极端及硬件或软件资源,叫做资源限制。

  • 硬件限制:比如 带宽、硬盘读写速度、CPU处理速度等。
  • 软件限制:比如 数据库连接数,sock连接数等。

对于硬件的限制,可以考虑使用集群。比如使用 ODPS、Hadoop或者自己搭建集群。

对于软件资源的限制,可以考虑使用资源池将资源复用。

小结

本文主要说明了在并发编程中遇到几个的挑战,建议使用 JDK 并发包中的提供的并发容器和工具类来解决这一类问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值