在多线程编程中,由于代码的并发执行,导致了不同的线程在修改相同的变量会导致变量的值错误
比如 变量 c = 2,这里有线程A 和 B一起使用 c变量并对他加1,这时就会有多中情况
这里要注意的是变量c是储存在内存中的,而线程要使用变量就需要吧变量读取都寄存器中,在对他进行操作
1 A B 同时得到了c 那么,c在A中的值为2,c在B中的值也为2,那么对他进行加一,那么最终结果c的值就是3 这就产生内存可见性的问题
内存可见性:当多个线程同时对一个变量进行修改时,线程不会再第一时间获取到变量对象的数据,就会导致一些不可预测的错误
比如我要对变量 a 通过俩个线程一起对他进行10000次的加一操作
发现最终的结果不是20000,这就是内存可见性引起的错误,且这个值是随机的
2 A 先得到了c 并对他进行了修改,B再得到了A修改后得c再对他进行操作,这样c得值就是4
而这样程序就充满得不确定性,为了避免这个问题,所以我们使用synchronized关键字来给线程上锁
synchronized使用
synchronized(锁对象){
//具体的逻辑实现
}
互斥访问
对于加了synchronized的代码块会在一个线程获得锁后执行对应的逻辑,在逻辑执行完后解锁,这时起他的线程才能获取锁,否者线程就会进入阻塞等待过程中,这样就能解决内存可见性的问题
可重入锁
java中实现了可重入锁,也就是对于相同锁对象的锁可以重复进入,不需要等他解锁
比如这样还是能正常运行,最有效的锁就只有最外层的锁,实现的方式通过一个count变量,从第一个synchronized开始遇到一个{ 就加加遇到 } 就减减最终中但count==0是就是解锁的时候
死锁
在一个锁a中尝试获取锁b,再另一个线程锁b又去获取a这样形成了个循环就会出现死锁的情况
对于死锁的解决方法可以规定每把锁的索取顺序,必须要等锁1 获取了才能锁2,否者就进入阻塞等待的情况,这样就能很好的避免死锁