我是看了这篇文章后总结一下问题,希望以后能够注意这些问题:
package w0141112;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* User: zhijun.he@renren-inc.com
* Date: 2014/11/12.
*/
public class TestMultiThread implements Runnable {
private static int i;
private static volatile Integer vi = 0;
private static AtomicInteger ai = new AtomicInteger();
private static Integer si = 0;
private static int ri;
private static AtomicInteger flag = new AtomicInteger();
private Lock lock = new ReentrantLock();
public void run() {
for (int k = 0; k < 200000; k++) {
i++;
vi++;
ai.incrementAndGet();
synchronized (si) {
si++;
}
lock.lock();
try {
ri++;
} finally {
lock.unlock();
}
}
flag.incrementAndGet();
}
public static void main(String[] args) throws InterruptedException {
TestMultiThread t1 = new TestMultiThread();
TestMultiThread t2 = new TestMultiThread();
ExecutorService exec1 = Executors.newCachedThreadPool();
ExecutorService exec2 = Executors.newCachedThreadPool();
exec1.execute(t1);
exec2.execute(t2);
while (true) {
if (flag.intValue() == 2) {
System.out.println("i " + i);
System.out.println("vi " + vi);
System.out.println("ai " + ai);
System.out.println("si " + si);
System.out.println("ri " + ri);
break;
}
Thread.sleep(50);
}
exec1.shutdown();
exec2.shutdown();
}
}
输出:
i 398728
vi 363257
ai 400000
si 355444
ri 396292
问题:
1.奇怪的是synchronized并没有起到多线程的加锁效果
2.try lock貌似也没有
3.原子类起到了作用(因为它是线程安全的,是用CAS实现的)
解释:
1.原博客的解释我是没看懂,或许是java存在的缺陷。但是我想说的是如何避免这个问题,这才是我真正关心的。现实编码中,其实你根本不会出现这种情况,为什么呢?因为一般代码从来没有可能对于锁去进行操作。也就是指
synchronized (si) {
si++;
}
完全可以用其他静态字段代替synchronized(si)
2.try lock没起作用这真的是原作者写错了,如果把字段改成静态就ok了。
private static Lock lock = new ReentrantLock();