并发编程(二)

简介: 并发编程(二)

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

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

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

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

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

代码演示下:

  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

相关文章
|
2月前
|
存储 安全 Java
并发编程篇
并发编程篇
|
3月前
|
Java 调度
并发编程(三)
并发编程(三)
|
3月前
|
算法 Java Go
并发编程(一)
并发编程(一)
|
存储 缓存 安全
多线程与并发编程面试题
多线程与并发编程
66 0
多线程与并发编程面试题
|
缓存 安全
并发编程学习一
并发编程学习一
80 0
|
Java 编译器 程序员
高并发编程-happens-before
高并发编程-happens-before
94 0
|
前端开发 C++
C++并发编程(下)
C++并发编程(下)
169 0
C++并发编程(下)
|
Ubuntu 大数据 编译器
C++并发编程(上)
C++并发编程
270 0
C++并发编程(上)
|
缓存 监控 安全
聊聊并发编程的10个坑
聊聊并发编程的10个坑
聊聊并发编程的10个坑
|
应用服务中间件 Go PHP
你真的了解并发编程吗?
1、进程和线程 a)进程:是系统进行资源分配和调度的基本单位 i.每一个php脚本被运行都会开启一个进程 1. 在nginx:php-fpm 2. 在apache:CGI b)进程包含线程,线程是我们程序的一个执行单元,负责执行