物业管理网站开发背景,360搜索联盟网站制作,公司域名备案全部过程,岳阳市城市建设投资公司网站锁其是用来控制在某些场景下让代码串行的工具。我们为了充分利用计算机的硬件性能#xff0c;发明了多线程#xff0c;多线程有好处#xff0c;但同时也有它复杂的一面#xff0c;必须控制好多个线程的执行#xff0c;才能驯服这个有能力也有脾气的烈马。 一、加锁范围误区…锁其是用来控制在某些场景下让代码串行的工具。我们为了充分利用计算机的硬件性能发明了多线程多线程有好处但同时也有它复杂的一面必须控制好多个线程的执行才能驯服这个有能力也有脾气的烈马。 一、加锁范围误区
下面add()方法加了锁的但是compare()方法中还是会出现a ! b的场景。必须要考虑锁的范围。add()方法加了同步只会保证多个线程在执行add()方法是串行的也即保证a和b一起递增。但是compare()方法并不和add()方法串行所以当add()方法执行到一半时是有可能执行compare()方法也就是出现a大于b的情况。
Slf4j
public class Test {public static void main(String[] args) {Test test new Test();new Thread(()-test.add()).start();new Thread(()-test.compare()).start();}volatile int a 1;volatile int b 1;public synchronized void add() {log.info(add start);for (int i 0; i 10000; i) {a;b;}log.info(add done);}public void compare() {log.info(compare start);for (int i 0; i 10000; i) {if (a ! b) {log.info(a:{},b:{},{}, a, b, a b);}}log.info(compare done);}} 执行结果 二、 锁级别的误判
要让多个线程串行执行宗旨就是让他们去争同一个东西我们姑且把这个东西称为锁。在JAVA中锁可以为类级别和实例级别。
下面代码中add()方法就是实例级别的锁导致多线程下不同实例并不会串行但是coun又是多线程共享的导致自增操作被破坏无法达到预期的值。
Slf4j
public class Test {private static int count;public static void main(String[] args) {IntStream.rangeClosed(1, 1000).parallel().forEach(i - new Test().add());log.info(count{}, Test.count);}public synchronized void add() {count;}
}
执行结果