我们知道不变对象是指一旦创建不能修改内部状态的对象,因为不变对象没有提供可供修改内部状态的方法,所以不变对象是线程安全的。但是String,当然包括其他的基本数据的包装类,如Integer/Long/Float等等,也是不变对象,但却是可以修改值的,这怎么保证线程安全?
public class Test{
private String str;
public void test(){
if(("").equals(str)){ //多个线程同时判断,可能导致多次执行
str = "1";
//do something
}
}
}
잠글 수 있는 다른 개체를 찾아 잠근 다음 문자열을 수정하세요.
으아악Java에서는 문자열 유형 객체 자체가 불변입니다. String은 상수 풀이라는 메모리 영역에 저장되기 때문입니다.
으아악예를 들어
출력:
으아악그럼 왜 또 변덕을 느끼는 걸까요?
으아악그러면 a는 test1이 됩니다. 실제로 여기에 새로운 "test1" 문자열 개체가 생성됩니다(상수 풀에 이 값이 없으면 새로 생성됩니다). 그런 다음 변수 참조를 지정하십시오. 참고: "test" 변수의 내부 상태는 여기에서 수정되지 않습니다. "test" 문자열 개체는 스레드로부터 안전합니다.
final로 수정하지 않는 한 모든 변수 포인트는 변경 가능합니다.
이 경우 스레드 안전성을 보장하려면:
아니요 0: 가시성을 보장하기 위해 휘발성 사용을 고려할 수 있습니다.
첫째, 최종 수정을 사용할 수 있습니다
둘째, AtomicReference와 같은 Atomic 객체를 사용할 수 있습니다. Integer의 경우 AtomicInteger 등도 있습니다
셋째, 해당 코드 영역을 잠급니다