public class StringLock {
public static int index = 0;
/**
* 目的:巧用String常量池的特性,加锁
*
* intern用来返回常量池中的某字符串,如果常量池中已经存在该字符串,则直接返回常量池中该对象的引用。
* 否则,在常量池中加入该对象,然后 返回引用。
*
* @param playerId
* @return
*/
public static String getLock(int playerId) {
return String.valueOf(playerId).intern();
}
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 5; i++) {
new Thread(new Runnable() {
@Override
public void run() {
String lock = getLock(index);
synchronized (lock) {
// 登陆逻辑
int temp = index;
temp++;
index = temp;
System.out.println(index);
}
}
}).start();
}
}
}
未加intern时多线程调试(发现:在Thread0进来时,Thread1还是可以进来的)
加了intern时多线程调试(Thread0进来后,Thread1则会被挂起)
总结:要拿String作为锁,必须加intern