并发编程(二)

简介: 并发编程(二)

一、并发编程所带来的另外一个挑战-死锁

在我们的开发过程中,或多或少遇到过并发的死锁的问题

举个生活中的例子:比如我们小的时候打架,很喜欢抓对方的头发的

①、我自己捂住自己的头发,然后我尝试去抓对方的头发,然而对方也捂住自己的头发,然而它也想抓我的头发,那么这回就处于一种僵局,也有可能我抓不住对方的头发,对方也抓不住我的头发,这时两个人在这里僵持着,这就很像在我们并发编程中的死锁。

②、也就是大家各有手头上的资源,然后去访问对方的资源,可以通过两个对象来代替两个锁

代码演示下:

  1. package com.weizhaoyang;


  2. public class DeadThreadDemo {
  3.    private  static final  Object HAIR_A=new Object();
  4.    private  static final  Object HAIR_B=new Object();

  5.    public static void main(String[] args) {
  6.        new Thread(()->{
  7.            synchronized (HAIR_A){
  8.                synchronized(HAIR_B){
  9.                    try {
  10.                        Thread.sleep(5000000);
  11.                    } catch (InterruptedException e) {
  12.                        e.printStackTrace();
  13.                    }
  14.                    System.out.println("A成功抓住B的头发");
  15.                }
  16.            }
  17.        }).start();
  18.        new Thread(()->{
  19.            synchronized (HAIR_B){
  20.                synchronized (HAIR_A){
  21.                    System.out.println("B成功抓住A的头发");
  22.                }
  23.            }
  24.        }).start();;
  25.    }
  26. }

运行的结果如下:这就是产生死锁了

二、并发编程所带来的另外一个挑战-线程安全的问题

线程的安全的问题和死锁的区别非常大:

①、死锁的状态好判断,它会处于一种僵持的状态,可以通过jdk提供的相应的工具,可以非常快速的定位到这个问题。

②、线程安全性问题,你去运行的时候,它并没有很明显的特征,比如说运行起来看起来是非常正常的。

代码如下:

  1. package com.weizhaoyang;


  2. import java.util.concurrent.CountDownLatch;

  3. public class UnSafeDemo {
  4.    private static int num=0;
  5.    private static CountDownLatch    countDownLatch=new CountDownLatch(10);
  6.    public  static void inCreate(){
  7.        num++;
  8.    }

  9.    public static void main(String[] args) {
  10.             for(int i=0;i<10;i++){
  11.                  new Thread(()->{
  12.                        for(int j=0;j<100;j++){
  13.                            inCreate();
  14.                        }
  15.                  }).start();
  16.                  countDownLatch.countDown();
  17.             }
  18.             while(true){
  19.                 if(countDownLatch.getCount()==0){
  20.                     System.out.println(num);
  21.                     break;
  22.                 }
  23.             }
  24.       }
  25. }

运行的结果如下:这时的结果始终是小于1000的。

解释如下:可以用两个线程解释下:当线程1还没有执行到num++的时候,线程2就拿到了时间片,这时就把num++,这时就是两个线程的结果为1。所以10个线程各执行100次的时候结果小于1000.

三、并发编程所带来的另外一个挑战-资源的限制

这是一个外在的因素,在资源有限制的情况下,并不是开越多的线程越好

主要分为两个方面:①、硬件资源

                                       服务器:1m

                                       本机:    2m

                                带宽的大小会影响并发编程

                                还有硬盘读写的速度

                                cpu的大小,不会因为开起多个线程,就速度变快,有可能会变慢

                              ②、软件的资源

                                   数据库连接 500个连接, 1000个线程查询,并不会因此而加快

                                   或者socket编程。

var first_sceen__time = (+new Date()); if ("" == 1 && document.getElementById('js_content')) { document.getElementById('js_content').addEventListener("selectstart",function(e){ e.preventDefault(); }); }

阅读 45

相关文章
|
API
.net core工具组件系列之Autofac—— 第二篇:Autofac的3种依赖注入方式(构造函数注入、属性注入和方法注入),以及在过滤器里面实现依赖注入
本篇文章接前一篇,建议可以先看前篇文章,再看本文,会有更好的效果。前一篇跳转链接:https://www.cnblogs.com/weskynet/p/15046999.html
1128 0
.net core工具组件系列之Autofac—— 第二篇:Autofac的3种依赖注入方式(构造函数注入、属性注入和方法注入),以及在过滤器里面实现依赖注入
|
12月前
|
机器学习/深度学习 人工智能 自然语言处理
Granite 3.1:IBM 开源新一代可商用大语言模型,支持 128K 上下文长度、多语言和复杂任务处理
IBM 推出的 Granite 3.1 是一款新一代语言模型,具备强大的性能和更长的上下文处理能力,支持多语言和复杂任务处理。
561 0
Granite 3.1:IBM 开源新一代可商用大语言模型,支持 128K 上下文长度、多语言和复杂任务处理
|
机器学习/深度学习 并行计算 调度
CuPy:将 NumPy 数组调度到 GPU 上运行
CuPy:将 NumPy 数组调度到 GPU 上运行
555 1
|
存储 缓存 Java
(一) 玩命死磕Java内存模型(JMM)与 Volatile关键字底层原理
文章的阐述思路为:先阐述`JVM`内存模型、硬件与`OS`(操作系统)内存区域架构、`Java`多线程原理以及`Java`内存模型`JMM`之间的关联关系后,再对`Java`内存模型进行进一步剖析,毕竟许多小伙伴很容易将`Java`内存模型(`JMM`)和`JVM`内存模型的概念相互混淆,本文的目的就是帮助各位彻底理解`JMM`内存模型。
429 0
|
缓存 监控 算法
如何调整InnoDB的LRU算法以提高效率?
【5月更文挑战第14天】如何调整InnoDB的LRU算法以提高效率?
216 2
|
存储 缓存 算法
作者推荐 | 【深入浅出MySQL】「底层原理」探秘缓冲池的核心奥秘,揭示终极洞察
MySQL作为一个存储系统,有着一个关键的优化机制——缓冲池(buffer pool),它极大地提高了数据的访问效率,避免了频繁的磁盘IO操作。通过将常用的数据存储在内存中,MySQL可以快速响应查询请求,减少耗时的磁盘访问。这一优化机制在提升数据库性能方面起到了重要的作用。
703 7
作者推荐 | 【深入浅出MySQL】「底层原理」探秘缓冲池的核心奥秘,揭示终极洞察
|
缓存 Java 数据库连接
【Mybatis】说一下 mybatis 的一级缓存和二级缓存
【Mybatis】说一下 mybatis 的一级缓存和二级缓存
|
存储 安全 前端开发
如何实现扫码登陆 & 扫码登陆原理
如何实现扫码登陆 & 扫码登陆原理
784 0
|
缓存 移动开发 JavaScript
阿里云OSS设置跨域访问
阿里云OSS设置跨域访问
18476 1
|
存储 缓存 NoSQL
高性能的本地缓存方案选型,看这篇就够了!
高性能的本地缓存方案选型,看这篇就够了!
24497 0