暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

考大家一个问题:T.class 是单例的吗?

马士兵 2020-08-05
112

一个 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();
    }
  }
}


这些小实验的设计是比较考验功力的,学习线程的时候自己要多动手进行试验,任何一个理论,都可以进行验证。

如有收获请划至底部

点击“在看”支持,谢



关注马士兵

每天分享技术干货





点赞是最大的支持 

文章转载自马士兵,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论