线程安全
什么是线程安全
某个代码在单线程或者是多线程运行时没有出现bug就叫做线程安全
因为我们线程之间的调度是无序的也是随机调度的(抢占式执行)
当我们执行这两个线程时,希望输出的是10000000,但是我们这里的线程是存在线程安全问题的,因为这两个线程是并发执行的,count++是随机调度的,

什么是锁synchronized()
为了避免线程安全问题,通过锁竞争让第二线程的指令无法插入到第一个线程的指令,从而达到线程安全

锁的写法
1.可以在线程内加锁使用synchronized,在创建一个实例对象作为锁,确保在进行并发执行时只有一个线程可以执行count++,其他线程只能等待当前线程释放锁后才能进入同步块,由于synchronized的存在两个线程不会被同时修改


2.创建一个类和方法,在这个方法里面加锁,而这个锁里面的this就是当前对象,就是Test这个类,而我们后面调用的t.add也是在调用Test这个对象,所以就不会出现线程安全问题


3.把锁的参数写成类的对象


4.修饰普通方法,相当于给this加锁

synchronized是可重入的锁
当我们的代码中写成了重复嵌套锁的情况下,在第一次是成功上锁,在第二次加锁时就会判断当前线程是否为持有锁的线程,如果不是同一个线程就会进行阻塞,如果是同一个线程就不会再次进行上锁,锁内部有个计数器,只会在这个计数器进行++操作
在释放锁的时候也是一样的,会先释放里面的锁,让计数机--,真正释放锁是最外面的那一层


当我们把代码进行调整,jvm的优化方式就会根据代码变化进行优化,但是它什么时候触发优化,什么时候不触发优化都是不确定的

java中也提供了volatile可以强制关闭jvm的优化功能,但是相对应的执行速度和在内存中的开销就回变大,好处就是数据的准确性和逻辑性提高了

wait
让当前的代码主动放弃进入cpu调度(释放锁),进入阻塞等待,让后面的代码有机会拿到锁
notify
唤醒wait等待的线程重新加入到锁竞争
wait和notify都必须放在锁里面,且他们的对象必须是同一个,如果有多个线程有wait对象都是一样的情况下,notify是随机唤醒其中一个


浙公网安备 33010602011771号