Integer vs int
由一个多线程共享Integer类变量问题引起的。。。
中,解释了为什么锁不住Integer对象,本次我们做一些实践
import java.util.Date;
/**
* https://www.cnblogs.com/silyvin/p/11475233.html
* Created by sunyuming on 19/8/28.
*/
public class MultiLock {
public Integer lockInteger;
public String lockString;
public String lockStringNew;
public static void main(String [] f) throws InterruptedException {
MultiLock a = new MultiLock();
MultiLock b = new MultiLock();
a.lockInteger = 127;
b.lockInteger = 127;
a.lockString = "abc";
b.lockString = "abc";
a.lockStringNew = new String("abc");
b.lockStringNew = new String("abc");
System.out.println("
当127自动装箱Integer时");
new Thread(new MyThreadInteger(a)).start();
new Thread(new MyThreadInteger(b)).start();
Thread.sleep(10000);
a.lockInteger = 128;
b.lockInteger = 128;
System.out.println("
当128自动装箱Integer时");
new Thread(new MyThreadInteger(a)).start();
new Thread(new MyThreadInteger(b)).start();
Thread.sleep(10000);
a.lockInteger = new Integer(127);
b.lockInteger = new Integer(127);
System.out.println("
当Integer堆时");
new Thread(new MyThreadInteger(a)).start();
new Thread(new MyThreadInteger(b)).start();
Thread.sleep(10000);
System.out.println("
当String常量池装箱时");
new Thread(new MyThreadString(a)).start();
new Thread(new MyThreadString(b)).start();
Thread.sleep(10000);
System.out.println("
当String堆时");
new Thread(new MyThreadStringNew(a)).start();
new Thread(new MyThreadStringNew(b)).start();
Thread.sleep(10000);
System.out.println("
当String堆intern时");
new Thread(new MyThreadStringNewIntern(a)).start();
new Thread(new MyThreadStringNewIntern(b)).start();
}
public void testIntegerLock() {
System.out.println("testIntegerLock" + System.identityHashCode(lockInteger));
synchronized (lockInteger) {
try {
System.out.println("starttestIntegerLock" + new Date());
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void testStringLock() {
System.out.println("testStringLock" + System.identityHashCode(lockString));
synchronized (lockString) {
try {
System.out.println("starttestStringLock"+ new Date());
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void testStringNewLock() {
System.out.println("testStringNewLock" + System.identityHashCode(lockStringNew));
synchronized (lockStringNew) {
try {
System.out.println("starttestStringNewLock"+ new Date());
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void testStringNewInternLock() {
System.out.println("testStringNewInternLock" + System.identityHashCode(lockStringNew.intern()));
synchronized (lockStringNew.intern()) {
try {
System.out.println("starttestStringNewInternLock"+ new Date());
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static class MyThreadInteger implements Runnable {
private MultiLock multiLock;
public MyThreadInteger(MultiLock multiLock) {
this.multiLock = multiLock;
}
@Override
public void run() {
this.multiLock.testIntegerLock();
}
}
public static class MyThreadString implements Runnable {
private MultiLock multiLock;
public MyThreadString(MultiLock multiLock) {
this.multiLock = multiLock;
}
@Override
public void run() {
this.multiLock.testStringLock();
}
}
public static class MyThreadStringNew implements Runnable {
private MultiLock multiLock;
public MyThreadStringNew(MultiLock multiLock) {
this.multiLock = multiLock;
}
@Override
public void run() {
this.multiLock.testStringNewLock();
}
}
public static class MyThreadStringNewIntern implements Runnable {
private MultiLock multiLock;
public MyThreadStringNewIntern(MultiLock multiLock) {
this.multiLock = multiLock;
}
@Override
public void run() {
this.multiLock.testStringNewInternLock();
}
}
}
当127自动装箱Integer时
testIntegerLock1842818263
testIntegerLock1842818263
starttestIntegerLockWed Dec 11 11:52:04 CST 2019
starttestIntegerLockWed Dec 11 11:52:09 CST 2019
当128自动装箱Integer时
testIntegerLock2025391892
testIntegerLock755079750
starttestIntegerLockWed Dec 11 11:52:14 CST 2019
starttestIntegerLockWed Dec 11 11:52:14 CST 2019
当Integer堆时
testIntegerLock455290755
testIntegerLock2078391126
starttestIntegerLockWed Dec 11 11:52:24 CST 2019
starttestIntegerLockWed Dec 11 11:52:24 CST 2019
当String常量池装箱时
testStringLock440496836
starttestStringLockWed Dec 11 11:52:34 CST 2019
testStringLock440496836
starttestStringLockWed Dec 11 11:52:39 CST 2019
当String堆时
testStringNewLock835411425
testStringNewLock872854004
starttestStringNewLockWed Dec 11 11:52:44 CST 2019
starttestStringNewLockWed Dec 11 11:52:44 CST 2019
当String堆intern时
testStringNewInternLock440496836
testStringNewInternLock440496836
starttestStringNewInternLockWed Dec 11 11:52:54 CST 2019
starttestStringNewInternLockWed Dec 11 11:52:59 CST 2019
Process finished with exit code 0
装箱过程是通过调用包装器的valueOf方法实现的,而拆箱过程是通过调用包装器的 xxxValue方法实现的。
在通过valueOf方法创建Integer对象的时候,如果数值在[-128,127]之间,便返回指向IntegerCache.cache中已经存在的对象的引用;否则创建一个新的Integer对象。

a+b,会先各自调用intValue方法,得到了加法运算后的数值之后,便调用Integer.valueOf方法
https://www.cnblogs.com/dolphin0520/p/3780005.html