±à¼ÍƼö: |
±¾ÎÄÖ÷Òª½éÉÜÁËḬ̈߳²È«·½·¨µÄÖØÐ´
¡¢¹¹Ô캯ÊýÖÐthisµÄÒç³ö¡¢²»ÒªÔÚÀà³õʼ»¯µÄʱºòʹÓúǫ́Ïß³ÌÕâ¸ö¼¸¸ö·½Ãæ¡£
±¾ÎÄÀ´×ÔÓÚ¹«Öںš¸³ÌÐòÄÇЩÊ¡¹£¬ÓÉ»ðÁú¹ûÈí¼þAnna±à¼¡¢ÍƼö¡£ |
|
¼ò½é
Èç¹ûÎÒÃÇÔÚ¶àÏß³ÌÖÐÒýÈëÁ˹²Ïí±äÁ¿£¬ÄÇôÎÒÃǾÍÐèÒª¿¼ÂÇһ϶àÏß³ÌÏÂḬ̈߳²È«µÄÎÊÌâÁË¡£ÄÇôÎÒÃÇÔÚ±àд´úÂëµÄ¹ý³ÌÖУ¬ÐèҪעÒâÄÄЩḬ̈߳²È«µÄÎÊÌâÄØ£¿
Ò»ÆðÀ´¿´¿´°É¡£
×¢ÒâḬ̈߳²È«·½·¨µÄÖØÐ´
´ó¼Ò¶¼×ö¹ý·½·¨ÖØÐ´£¬ÎÒÃÇÖªµÀ·½·¨ÖØÐ´ÊDz»»á¼ì²é·½·¨ÐÞÊηûµÄ£¬Ò²¾ÍÊÇ˵£¬ÎÒÃÇ¿ÉÒÔ½«Ò»¸ösynchronizedµÄ·½·¨ÖØÐ´³ÉΪ·ÇḬ̈߳²È«µÄ·½·¨£º
public class
SafeA {
public synchronized void doSomething(){
}
} |
public class
UnsafeB extends SafeA{
@Override
public void doSomething(){
}
} |
ÎÒÃÇÔÚʵÏÖ×ÓÀ๦ÄܵÄʱºò£¬Ò»¶¨Òª±£³Ö·½·¨µÄḬ̈߳²È«ÐÔ¡£
¹¹Ô캯ÊýÖÐthisµÄÒç³ö
thisÊÇÊ²Ã´ÄØ£¿¸ù¾ÝJLSµÄ¹æ·¶£¬µ±ÓÃ×÷Ö÷Òª±í´ïʽʱ£¬¹Ø¼ü×Öthis±íʾһ¸öÖµ£¬¸ÃÖµÊÇ¶ÔÆäµ÷ÓÃʵÀý·½·¨µÄ¶ÔÏó»òÕýÔÚ¹¹ÔìµÄ¶ÔÏóµÄÒýÓá£
ÄÇôÎÊÌâÀ´ÁË£¬ÒòΪthisÄܹ»±íʾÕýÔÚ¹¹ÔìµÄ¶ÔÏó£¬ÄÇôÒâζ×Å£¬Èç¹û¶ÔÏó»¹Ã»Óй¹½¨Íê±Ï£¬¶øthisÓÖ¿ÉÒÔ±»Íⲿ·ÃÎʵϰ£¬¾Í»áÔì³ÉÍⲿ¶ÔÏó·ÃÎʵ½»¹Î´¹¹Ôì³É¹¦¶ÔÏóµÄÎÊÌâ¡£
ÎÒÃÇÀ´¾ßÌå¿´Ò»ÏÂthisÒç³ö¶¼»á·¢ÉúÔÚÄÄЩÇé¿ö£º
public class
ChildUnsafe1 {
public static ChildUnsafe1 childUnsafe1;
int age; ChildUnsafe1(int age){
childUnsafe1 = this;
this.age = age;
}
} |
ÉÏÃæÊÇÒ»¸ö·Ç³£¼òµ¥µÄthisÒç³öµÄÇé¿ö£¬ÔÚ¹¹Ô캯ÊýµÄ¹ý³ÌÖУ¬½«this¸³Öµ¸øÁËÒ»¸öpublic¶ÔÏ󣬽«»áµ¼ÖÂthis»¹Ã»Óб»³õʼ»¯Íê±Ï¾Í±»ÆäËû¶ÔÏó·ÃÎÊ¡£
ÄÇôÎÒÃǵ÷ÕûÒ»ÏÂ˳ÐòÊDz»ÊǾͿÉÒÔÁËÄØ£¿
public class
ChildUnsafe2 {
public static ChildUnsafe2 childUnsafe2;
int age; ChildUnsafe2(int age){
this.age = age;
childUnsafe2 = this;
}
} |
ÉÏÃæÎÒÃÇ¿´µ½£¬thisµÄ¸³Öµ±»·Åµ½Á˹¹Ôì·½·¨µÄ×îºóÃæ£¬ÊDz»ÊǾͿÉÒÔ±ÜÃâ·ÃÎʵ½Î´³õʼ»¯Íê±ÏµÄ¶ÔÏóÄØ£¿
´ð°¸ÊÇ·ñ¶¨µÄ£¬ÒòΪjava»á¶Ô´úÂë½øÐÐÖØÅÅÐò£¬ËùÒÔchildUnsafe2 = thisµÄλÖÃÊDz»¶¨µÄ¡£
ÎÒÃÇÐèÒªÕâÑùÐ޸ģº
public class
Childsafe2 {
public volatile static Childsafe2 childUnsafe2;
int age; Childsafe2(int age){
this.age = age;
childUnsafe2 = this;
}
} |
¼ÓÒ»¸övolatileÃèÊö·û£¬½ûÖ¹ÖØÅÅÐò£¬ÍêÃÀ½â¾ö¡£
ÎÒÃÇÔÙÀ´¿´Ò»¸ö¸¸×ÓÀàµÄÎÊÌ⣬»¹ÊÇÉÏÃæµÄChildsafe2£¬ÎÒÃÇÔÙΪËüдһ¸ö×ÓÀࣺ
public class
ChildUnsafe3 extends Childsafe2{ private Object obj; ChildUnsafe3(int age){
super(10);
obj= new Object();
} public void doSomething(){
System.out.println(obj.toString());
}
} |
ÉÏÃæµÄÀý×ÓÓÐʲôÎÊÌâÄØ£¿ÒòΪ¸¸ÀàÔÚµ÷Óù¹Ô캯ÊýµÄʱºò£¬ÒѾ±©Â¶ÁËthis±äÁ¿£¬ËùÒÔ¿ÉÄܻᵼÖÂChildUnsafe3ÖеÄobj»¹Ã»Óб»³õʼ»¯µÄʱºò£¬Íⲿ³ÌÐò¾Íµ÷ÓÃÁËdoSomething()£¬Õâ¸öʱºòobj»¹Ã»Óб»³õʼ»¯£¬ËùÒÔ»áÅ׳öNullPointerException¡£
½â¾ö°ì·¨¾ÍÊDz»ÒªÔÚ¹¹Ô캯ÊýÖÐÉèÖÃthis£¬ÎÒÃÇ¿ÉÒÔд´½¨Ò»¸ö·½·¨£¬ÔÚ¹¹Ô캯Êýµ÷ÓÃÍê±ÏÖ®ºó£¬ÔÙ½øÐÐÉèÖá£
²»ÒªÔÚÀà³õʼ»¯µÄʱºòʹÓúǫ́Ïß³Ì
Èç¹ûÔÚÀà³õʼ»¯µÄ¹ý³ÌÖУ¬Ê¹Óúǫ́½ø³Ì£¬ÓпÉÄÜ»áÔì³ÉËÀËø£¬ÎÒÃÇ¿¼ÂÇÏÂÃæµÄÇé¿ö£º
public final
class ChildFactory {
private static int age; static {
Thread ageInitializerThread = new Thread(()->{
System.out.println("in thread running");
age=10;
}); ageInitializerThread.start();
try {
ageInitializerThread.join();
} catch (InterruptedException ie) {
throw new AssertionError(ie);
}
} public static int getAge() {
if (age == 0) {
throw new IllegalStateException("Error
initializing age");
}
return age;
} public static void main(String[] args) {
int age = getAge();
}
} |
ÉÏÃæµÄÀàʹÓÃÁËÒ»¸östaticµÄblock£¬ÔÚÕâ¸öblockÖУ¬ÎÒÃÇÆô¶¯Ò»¸öºǫ́½ø³ÌÀ´ÉèÖÃageÕâ¸ö×ֶΡ£
ΪÁ˱£Ö¤¿É¼ûÐÔ£¬static±äÁ¿±ØÐëÔÚÆäËûÏß³ÌÔËÐÐ֮ǰ³õʼ»¯Íê±Ï£¬ËùÒÔageInitializerThreadÐèÒªµÈ´ýmainÏ̵߳Ästatic±äÁ¿Ö´ÐÐÍê±ÏÖ®ºó²ÅÄÜÔËÐУ¬µ«ÊÇÎÒÃÇÓÖµ÷ÓÃÁËageInitializerThread.join()·½·¨£¬Ö÷Ïß³ÌÓÖÐèÒª·´¹ýÀ´µÈ´ýageInitializerThreadµÄÖ´ÐÐÍê±Ï¡£
×îÖÕµ¼ÖÂÁËÑ»·µÈ´ý£¬Ôì³ÉÁËËÀËø¡£
×î¼òµ¥µÄ½â¾ö°ì·¨¾ÍÊDz»Ê¹Óúǫ́½ø³Ì£¬Ö±½ÓÔÚstatic blockÖÐÉèÖãº
public final
class ChildFactory2 {
private static int age; static {
System.out.println("in thread running");
age=10;
} public static int getAge() {
if (age == 0) {
throw new IllegalStateException("Error
initializing age");
}
return age;
} public static void main(String[] args) {
int age = getAge();
}
} |
»¹ÓÐÒ»ÖÖ°ì·¨¾ÍÊÇʹÓÃThreadLocal½«³õʼ»¯±äÁ¿±£´æÔÚÏ̱߳¾µØ¡£
public final
class ChildFactory3 { private static final ThreadLocal<Integer>
ageHolder = ThreadLocal.withInitial(() ->
10); public static int getAge() {
int localAge = ageHolder.get();
if (localAge == 0) {
throw new IllegalStateException("Error
initializing age");
}
return localAge;
} public static void main(String[] args) {
int age = getAge();
}
} |
±¾ÎĵĴúÂë
|