解决方案 »

  1.   

    第一个例子就是线程安全的,没必要弄成第二那样。
    虽然你的两个线程使用的是同一个OutPut对象,但是你的output方法内并没有使用到多条线程共享的内容。
      

  2.   

    你确定你没看走眼?output方法是一个字符一个字符地输出,这里启动了两个线程可能同时调用output方法,那么就有可能两个结果的字符穿插在一起,而这应该不是output方法设计时希望看到的吧。
      

  3.   

    It should be not thread safe. In Case:
    Thread A : 
    access the output function, 
    when it assign the name and len, but not access the synchronized block
    Thread B: access the output function, and assign the name and len as well. 
    Then Thread A will print wrong information.So it should be not safe.
      

  4.   

    的确不是线程安全的,但是我们普通用的工具类,
        public static boolean isNumber(String str){
            Pattern pattern = Pattern.compile("^[0-9]+$");
            return  pattern.matcher(str).find();
        }这个呢 是线程安全的吗?
      

  5.   

    的确不是线程安全的,但是我们普通用的工具类,
        public static boolean isNumber(String str){
            Pattern pattern = Pattern.compile("^[0-9]+$");
            return  pattern.matcher(str).find();
        }这个呢 是线程安全的吗?
    这当然是安全的,又没有共享资源
      

  6.   

    楼上的一些,我不得不说在误人子弟,现在楼主是模拟的举的线程安全的例子,你们非要紧扣线程安全是共享变量的访问,这样来回答问题,明显就是敷衍。从模拟的效果看,如果一个方法的一个字符串没在一行打印那就认为线程不安全(因为实际结果不是预想)。 好了,回答楼主问题,第一个不是线程安全,因为两个线程同时操作没有加锁的打印方法,第一个线程打印几个字符后,CPU时间片可能会切到第二个线程打印字符,这样就混乱。第二个类的方法的打印加了同步锁,很明显哪个线程先进来就保证把传进的字符串打印完才允许第二个线程进来打印。
      

  7.   

    synchronized 加锁能很好的避免多线程冲突问题
      

  8.   

    我上面给的两个例子也没有共享资源,但并不是线程安全的,这个如何解释呢?
    的确不是线程安全的,但是我们普通用的工具类,
        public static boolean isNumber(String str){
            Pattern pattern = Pattern.compile("^[0-9]+$");
            return  pattern.matcher(str).find();
        }这个呢 是线程安全的吗?的确不是线程安全的,但是我们普通用的工具类,
        public static boolean isNumber(String str){
            Pattern pattern = Pattern.compile("^[0-9]+$");
            return  pattern.matcher(str).find();
        }这个呢 是线程安全的吗?
      

  9.   

    那我们平时用的工具类,也不是线程安全的吗?
     public static boolean isNumber(String str){
            Pattern pattern = Pattern.compile("^[0-9]+$");
            return  pattern.matcher(str).find();
        }
      

  10.   

    那我们平时用的工具类,也不是线程安全的吗?
     public static boolean isNumber(String str){
            Pattern pattern = Pattern.compile("^[0-9]+$");
            return  pattern.matcher(str).find();
        }
    但是我标题的那个例子也没有共享资源呀  怎么不是线程安全的呢
      

  11.   


    确实,你这个程序是模拟线程不安全,而不是真正的线程不安全。
    给你写了一个真正线程不安全的例子,你自己运行一下,仔细分析下结果,线程这种东西需要认真细心学才能搞懂,旁人几句话也说不通。
    public class ThreadTest {
    private int i = 0; public static void main(String[] args) {
    ThreadTest threadTest = new ThreadTest();
    new Thread(threadTest.new MyThread(), "a").start();
    new Thread(threadTest.new MyThread(), "b").start();
    } class MyThread implements Runnable { @Override
    public void run() {
    while (true) {
    System.out.println("线程" + Thread.currentThread().getName()
    + "运行中,现在的i值为:" + i);
    try {
    Thread.sleep(1000);//线程读完i后,睡眠1秒钟再对i进行修改,以便分析。
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println("线程" + Thread.currentThread().getName()
    + "运行中,经过++i后,现在的i值为:" + ++i);
    }
    } }
    }这个例子中,a、b两条线程都会去读写共享变量i值,现在会可能出现某个时候这样的情况:
    线程a把i值读进来了值是0,相当于a.i==0,然后a睡眠1秒;
    这时候到b线程开始读,这时候i值还是0,相当于b.i==0,b线程也开始睡眠1秒;
    然后是a线程睡眠结束它又开始执行了,这回是++a.i,然后线程a会将a.i的值也就是1传回到类变量i中,这时候类变量i的值为1;
    接下来b线程睡眠结束继续执行,这次是++b.i,结果b.i的值是1,然后b线程也将b.i的值传回到类变量i中,这个时候类变量i的值还是1。
    这时候问题就暴露出来了,明明是执行了两次的++操作,但有效的却只有一次,这不科学了。
    这个就是线程不安全的情况啦。
      

  12.   

    不好意思,我上面的例子有点问题,重新整理了下,希望对楼主有些帮助。
    public class ThreadTest {
    private int i = 0; public static void main(String[] args) {
    ThreadTest threadTest = new ThreadTest();
    new Thread(threadTest.new MyThread(), "a").start();
    new Thread(threadTest.new MyThread(), "b").start();
    } class MyThread implements Runnable { @Override
    public void run() {
    while (true) {
    System.out.println("线程" + Thread.currentThread().getName()
    + "运行中,经过++i后,现在的i值为:" + ++i);

    try {
    Thread.sleep(500);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    } }
    }
    注:一个线程操作共享变量时,会先到主内存空间获取这个变量副本到线程空间中,然后在线程空间对副本进行操作,最后再把操作结果写回到主内存中去。
    这个例子中,a、b两条线程都会去读写共享变量i值,现在会可能出现某个时候这样的情况:
    线程a把i值读进来了值是0,相当于a.i==0;
    这时候到b线程开始读,这时候i值还是0,相当于b.i==0;
    然后是轮到a线程它又开始执行了,这回是++a.i,然后线程a会将a.i的值也就是1传回到类变量i中,这时候类变量i的值为1;
    接下来b线程继续执行,这次是++b.i,结果b.i的值是1,然后b线程也将b.i的值传回到类变量i中,这个时候类变量i的值还是1。
    这时候问题就暴露出来了,明明是执行了两次的++操作,但有效的却只有一次,这不科学了。
    这个就是线程不安全的情况啦。