leeboysam
2014-06-15 20:42
浏览 195
已采纳

java多线程问题请教

大家好,小弟刚学多线程,有个概念一直没搞懂,之前一直说如果在方法在创建多个实例对象然后调用其方法不会有线程安全问题,就是struts2 都说每个请求创建了一个新的实例就不会有线程问题。

 

那我做了个例子,运行结果一直都有问题,特请教

 

有2个类

 

public class Outputter2 {

//输出name
 public void output(String name) {
  int len = name.length();   
   for (int i = 0; i < len; i++) {
    System.out.print(name.charAt(i));
   }
   System.out.println();
   }

}

 

///////////////////////////

public class Outputter4 implements Runnable {

 private String name;
 
 public Outputter4(String name){
  this.name = name;
 }
 
 @Override
 public void run() {

  while (true) {
   try {
    Thread.sleep(1000);
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   //System.out.println(name);
   new Outputter2().output(name);

  }
  
 }
 
 public static void main(String[] args) {

//每次都创建新的Outputter4
  new Thread(new Outputter4("aaaa")).start();
  new Thread(new Outputter4("bbbb")).start();
 }

}

 

打印效果,不正确:

aaaa
bbbb
abbbb
aaa
bbbb
aaaa
baaaa
bbb
aaaa

 请帮忙解释,我一直没弄明白错在那里?

 是不是由于name引起的,如果name不使用实例变量,怎么传递?

  在方法里使用对象变量是安全的是怎么解释?

 

谢谢!!!!

  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

7条回答 默认 最新

  • iteye_11694 2014-06-16 11:45
    已采纳

    我感觉你说的不正确是那因为打印出来的东西,不是aaaa bbbb 这种格式,而是有abbbb这种ab混合的形式,这个问题是因为jvm是的cpu是抢占式调度,也就是说相同的优先级,cpu会随机选择一个线程运行,而且一个线程没运行完有可能虚拟机也会让当前线程暂时放弃CPU,转到就绪状态,使其它线程获得运行机会。
    换句话说多个线程同时运行你根本控制不住。
    转到你的问题上,就是可能线程1运行for循环打印a的时候,线程2抢到cpu就打印b了,就这样交叉运行得到了你那结果。
    而你说的安全,多线程的时候安全主要针对的是共享资源的安全,你这上面各个线程各自new了自己的对象,用的都是局部变量,所以不存在线程安全问题。

    已采纳该答案
    评论
    解决 无用
    打赏 举报
  • runshine 2014-06-15 21:31

    挺正常的打印结果,有什么问题?
    你想是什么样的?

    评论
    解决 无用
    打赏 举报
  • grapeqin 2014-06-16 10:48
    线程安全问题一般是存在于多个线程对共享变量的操作才引起的,你这个示例不存在线程安全问题,因为两个线程分别使用的是两个不同的对象。
    至于你说的“在方法里使用对象变量是安全的是怎么解释?”方法内部的变量都是临时变量,临时变量不存在线程安全问题,这个是java变量作用域的概念。你可以在去找资料好好看看。
    
    评论
    解决 无用
    打赏 举报
  • sca4441479 2014-06-16 17:29

    线程安全是对多个线程操作改变一个对象的全局变量而言的,你这个没涉及线程安全问题,就是多个线程打印字母了,这个线程打a,那个线程打b,排在一起了

    评论
    解决 无用
    打赏 举报
  • tracy821 2014-06-16 19:14

    [code="java"]
    int len = name.length();

    for (int i = 0; i < len; i++) {
    System.out.print(name.charAt(i));
    }
    System.out.println();
    }
    [/code]

    在执行上述代码时“System.out.print(name.charAt(i))”代码会抢时间片,所以不可能你想的那样“aaaaa”、“bbbbbb”一起打印,代码执行没有问题。

    评论
    解决 无用
    打赏 举报
  • liujiafei_2007 2014-06-17 19:51

    public class Outputter2 {

    // 输出name
    public void output(String name) {
        int len = name.length();
        synchronized(Outputter2.class) {
        for (int i = 0; i < len; i++) {
            System.out.print(name.charAt(i));
        }
        System.out.println();
    }
    

    }
    Outputter2类改为如下再运行试试是否符合要求。ps:不好意思,第一次使用,之前发到评论那里了。

    评论
    解决 无用
    打赏 举报
  • yoyo837837 2014-09-15 11:54

    拜托用代码格式器,看到这种就不想仔细阅读.累啊

    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题