一、并发编程所带来的另外一个挑战-死锁
在我们的开发过程中,或多或少遇到过并发的死锁的问题
举个生活中的例子:比如我们小的时候打架,很喜欢抓对方的头发的
①、我自己捂住自己的头发,然后我尝试去抓对方的头发,然而对方也捂住自己的头发,然而它也想抓我的头发,那么这回就处于一种僵局,也有可能我抓不住对方的头发,对方也抓不住我的头发,这时两个人在这里僵持着,这就很像在我们并发编程中的死锁。
②、也就是大家各有手头上的资源,然后去访问对方的资源,可以通过两个对象来代替两个锁
代码演示下:
package com.weizhaoyang;
public class DeadThreadDemo {
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){
synchronized(HAIR_B){
try {
Thread.sleep(5000000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("A成功抓住B的头发");
}
}
}).start();
new Thread(()->{
synchronized (HAIR_B){
synchronized (HAIR_A){
System.out.println("B成功抓住A的头发");
}
}
}).start();;
}
}
运行的结果如下:这就是产生死锁了
二、并发编程所带来的另外一个挑战-线程安全的问题
线程的安全的问题和死锁的区别非常大:
①、死锁的状态好判断,它会处于一种僵持的状态,可以通过jdk提供的相应的工具,可以非常快速的定位到这个问题。
②、线程安全性问题,你去运行的时候,它并没有很明显的特征,比如说运行起来看起来是非常正常的。
代码如下:
package com.weizhaoyang;
import java.util.concurrent.CountDownLatch;
public class UnSafeDemo {
private static int num=0;
private static CountDownLatch countDownLatch=new CountDownLatch(10);
public static void inCreate(){
num++;
}
public static void main(String[] args) {
for(int i=0;i<10;i++){
new Thread(()->{
for(int j=0;j<100;j++){
inCreate();
}
}).start();
countDownLatch.countDown();
}
while(true){
if(countDownLatch.getCount()==0){
System.out.println(num);
break;
}
}
}
}
运行的结果如下:这时的结果始终是小于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