
一个 class load 到内存它不是单例的,想想看。
一般情况不是,如果是在同一个 ClassLoader 空间那它一定是。不是同一个类加载器就不是了,不同的类加载器互相之间也不能访问。所以说你能访问它,那他一定就是单例。
下面程序:很有可能读不到别的线程修改过的内容,除了这点之外 count-- 完了之后,下面的 count 输出和你减完的结果不对。
/**
* 分析一下这个程序的输出
* @author mashibing
*/
package com.mashibing.juc.c_005;
public class T implements Runnable {
private /*volatile*/ int count = 100;
public /*synchronized*/ void run() {
count--;
System.out.println(Thread.currentThread().getName() + " count = " + count);
}
public static void main(String[] args) {
T t = new T();
for(int i=0; i<100; i++) {
new Thread(t, "THREAD" + i).start();
}
}
}
很容易分析:如果有一个线程把它从10减到9了,然后又有一个线程在前面一个线程还没有输出来呢?进来了9又见到了8,继续输出的8,而不是9。如果你想修正它,前面第一个是在上面加volatile,改了马上就能得到。
另外这个之外还可以加 synchronized,加了 synchronized 就没有必要在加 volatile 了,因为 synchronized 既保证了原子性,有保证了可见性。
/**
* 对比上面一个小程序,分析一下这个程序的输出
* @author mashibing
*/
package com.mashibing.juc.c_006;
public class T implements Runnable {
private int count = 10;
public synchronized void run() {
count--;
System.out.println(Thread.currentThread().getName() + " count = " + count);
}
public static void main(String[] args) {
for(int i=0; i<5; i++) {
T t = new T();
new Thread(t, "THREAD" + i).start();
}
}
}
这些小实验的设计是比较考验功力的,学习线程的时候自己要多动手进行试验,任何一个理论,都可以进行验证。
如有收获请划至底部
点击“在看”支持,谢谢!
关注马士兵
每天分享技术干货
点赞是最大的支持








