在使用线程锁的时候对于一些不可变对象诸如String Integer等等可能会出现一些问题诸如下面代码:
public class ThreadSync implements Runnable{
static ThreadSync sync = new ThreadSync();
static Integer j=0;
public void inscane(){
for(int i=0;i<10000000;i++){
synchronized (j){
j++;
}
}
}
@Override
public void run() {
inscane();
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(sync);
Thread t2 = new Thread(sync);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(j);
}
}
上面代码执行出来的结果存在线程安全的;
1、由于Integer是不可变对象,当执行j++的时候实际上是生成了一个新的对象。此时由于synchronized (j);锁定的是不同的对象,所以拿到的不是同一把锁会出现安全问题。
解决方式:
1、把synchronized提升到方法级别。
2、改成synchronized (ThreadSync.class)
3、把Inetegr换成int
初次之外上面写法效率并不高,应该把synchronized 拿到for循环之外