一、实现网站访问计数器
1、线程不安全的做法
1.1、代码
package com.chentongwei.concurrency; import static java.lang.Thread.sleep; /** * @Description: * @Project concurrency */ public class TestCount { private static int count; public void incrCount() { count ++; } public static void main(String[] args) throws InterruptedException { TestCount testCount = new TestCount(); // 开启五个线程 for (int i = 0; i < 5; i++) { new Thread(() -> { try { sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } // 每个线程都让count自增100 for (int j = 0; j < 100; j++) { testCount.incrCount(); } }).start(); } sleep(2000); // 正确的情况下会输出500 System.out.println(count); } }
1.2、结果
并不一定是500,极大可能小于500。不固定。
1.3、分析
很明显上面那段程序是线程不安全的,为什么线程不安全?因为++操作其实是类似如下的两步骤,如下:
count ++; || // 获取count int temp = count; // 自增count count = temp + 1;
很明显是先获取在自增,那么问题来了,我线程A和线程B都读取到了int temp = count;
这一步,然后都进行了自增操作,其实这时候就错了因为这时候count丢了1,并发了。所以导致了线程不安全,结果小于等于500。
2、Synchronized保证线程安全
2.1、代码
package com.chentongwei.concurrency; import static java.lang.Thread.sleep; /** * @Description: * @Project concurrency */ public class TestCount { private static int count; public void incrCount() { count