专栏首页Spring相关并发编程情况下几个相应问题简介

并发编程情况下几个相应问题简介

1.并发编程的挑战之死锁

​ 死锁是两个或更多线程阻塞着等待其它处于死锁状态的线程所持有的锁。死锁通常发生在多个线程同时但以不同的顺序请求同一组锁的时候。

例如,如果线程1锁住了A,然后尝试对B进行加锁,同时线程2已经锁住了B,接着尝试对A进行加锁,这时死锁就发生了。线程1永远得不到B,线程2也永远得不到A,并且它们永远也不会知道发生了这样的事情。为了得到彼此的对象(A和B),它们将永远阻塞下去。这种情况就是一个死锁。

​ 举个例子:A和B打架,两人都想抓住对方的头发,于是我们可以依此编写如下的程序:

/**
 * 死锁
 */
public class DeadLockDemo {

    private static final Object HAIR_A = new Object();
    private static final Object HAIR_B = new Object();

    public static void main(String[] args) {

        new Thread(() -> {
            synchronized (HAIR_A) {
                try {
                    Thread.sleep(50L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (HAIR_B) {
                    System.out.println("A成功抓住B的头发");

                }
            }


        }).start();


        new Thread(() -> {
            synchronized (HAIR_B) {
                synchronized (HAIR_A) {
                    System.out.println("B成功抓住A的头发");

                }
            }
        }).start();
    }

}

​ 这个时候由于A和B都想要获取对方的锁,而双方都紧握不放,导致谁也抓不到谁,最终一直僵持下去,造成死锁的发生,这个时候我们可以用监视器查相应的死锁状况:

image

2.并发编程的挑战之线程安全

​ 线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。

​ 线程不安全就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据

下面我们来看一个例子,采取10个线程对num进行++的操作,此时会发现每次得到的结果都不一样;这个就是线程不安全造成的结果:

package xianchengxuexi;

import java.util.concurrent.CountDownLatch;

/**
 * 线程不安全操作
 */
public class UnSafeThread {

    private static int num = 0;
    private static CountDownLatch countDownLatch =new CountDownLatch(10);

    /**
     * 每次调用对num进行++的操作
     *
     */
    public static void  increment(){
        num++;
    }

    public static void main(String[] args) {

        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                for (int j = 0; j <100 ; j++) {
                    increment();
                    try {
                        Thread.sleep(10L);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                //在每个线程只想完后调用cutdown
                countDownLatch.countDown();
            }).start();

        }
        while (true){
            if(countDownLatch.getCount()==0){
                break;
            }
        }
        System.out.println(num);
    }
}

​ 此结果产生的原因用简图描述如下,就是在线程1睡眠的过程中,第二个线程进行了操作,但是拿到的结果仍然是未更新的值,也就是脏数据,这个进行操作就没有同步,造成线程不安全:

image

3.并发编程的挑战之资源挑战

  • 硬件资源
  • 服务器: 1m 本机:2m
  • 带宽的上传/下载速度、硬盘读写速度和CPU的处理速度。
  • 软件资源
  • 数据库连接 500个连接 1000个线程查询 并不会因此而加快 socket

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 线程安全相关问题总结

    当多个线程访问某个类,不管运行时环境采用何种调度方式或者这些线程如何交替执行,并且在主调代码中不需 要任何额外的同步或协同,这个类都能表现出正确的行为,那么就...

    Dream城堡
  • 带返回值的函数,闭包,沙箱,递归详解

    那了解了函数 this 指向的不同场景之后,我们知道有些情况下我们为了使用某种特定环境的 this 引用, 这时候时候我们就需要采用一些特殊手段来处理了,例如...

    Dream城堡
  • thymeleaf 传递数据到js变量

    Dream城堡
  • 谈Python多线程及程序锁

    Python中多线程使用到Threading模块。Threading模块中用到的主要的类是Thread,我们先来写一个简单的多线程代码:

    phith0n
  • 通俗易懂,各常用线程池的执行 流程图

    作者:林冠宏 / 指尖下的幽灵 腾讯云+社区:https://cloud.tencent.com/developer/user/1148436/activ...

    林冠宏-指尖下的幽灵
  • 多线程断点下载

    多线程断点下载 多线程下载 public class MultiThreadDownloader { private URL url; // 目...

    xiangzhihong
  • 通俗易懂,各常用线程池的执行 流程图

    corePoolSize,maximumPoolSize,workQueue之间关系。

    林冠宏-指尖下的幽灵
  • 通俗易懂,常用线程池执行的-流程图

    适合的读者,尽可能让你彻底明白 常用的线程池的知识相关点 不适合的读者,能有个不错的概念,神童另谈

    搜云库技术团队
  • Jmeter接口压测示例

    Apache JMeter™ 是 Apache 组织开发的一款开源软件,是典型的纯 Java 开发的应用程序,可以在不同平台比如Windows、Linux或ma...

    憧憬博客
  • 如何扩展和优化线程池?

    多线程的软件设计方法确实可以最大限度的发挥现代多核处理器的计算能力,提高生产系统的吞吐量和性能。但是,如果一个系统同时创建大量线程,线程间频繁的切换上下文导致的...

    本人秃顶程序员

扫码关注云+社区

领取腾讯云代金券