1

我在理解这段代码时遇到了问题,我的问题是为什么两个线程在执行方法中的语句时不会相互干扰run

我的意思是总是先做所有的陈述然后再来第二个线程做陈述。

第一个线程执行部分语句然后第二个线程执行部分语句然后第一个线程继续其任务是不可能的......

注意:我知道这两个线程使用不同的OutputStream对象

线程代码在这里

class Printer extends Thread
{
   private String ThreadName;

   public Printer(String name)
   {
       this.ThreadName=name;
   }

   public void run()
   {
       PrintStream out=new PrintStream(System.out);

       out.println(this.ThreadName+" : a");
       out.println(this.ThreadName+" : b");
       out.println(this.ThreadName+" : c");
       out.println(this.ThreadName+" : d");
       out.println(this.ThreadName+" : e");
       out.println(this.ThreadName+" : f");
       out.println(this.ThreadName+" : g");
       out.println(this.ThreadName+" : h");
       out.println(this.ThreadName+" : i");
       out.println(this.ThreadName+" : j");
       out.println(this.ThreadName+" : k");    
   }
}

进入代码:

class Main 
{
    public static void main(String[] args)
    {
        Thread t1 = new Printer("thread 1");
        Thread t2 = new Printer("thread 2");

        t1.start();
        t2.start();
    }
}

尝试替换System.outout比较结果,然后您将确切知道我要的是什么

4

2 回答 2

1

在解释之前有几件事:

不需要扩展Thread,只需实现更容易Runnable,它提供了run您正在实现的方法。在这一点上,你可以给RunnableaThread或更有用的是 an Executor(对于 Java 中的多线程非常有用)。

此外,包装System.out在 aPrintStream中是多余的,因为a本身System.out已经是多余的。PrintStream

最后,您的代码没有共享任何内容,这就是它们不会相互干扰的原因。每个人所做的只是打印出他们的名字和一个独特的字母,以便您找到它。 System.out在 Sun 实现中是线程安全的(正如 Andre 所指出的,这在技术上不是 JVM 实现所要求的),因此您将无法分解输出,但这不会阻止您潜在地交织输出。

例如,如果你运行得足够多,那么你可以很容易地看到:

thread 1 a
thread 2 a
thread 1 b
thread 2 b

但是,我怀疑您看到的是:

thread 1 a
    .
    .
    .
thread 1 k
thread 2 a
    .
    .
    .
thread 2 k

这不是因为某些东西被破坏了,而是因为线程执行得如此之快以至于它就是这样发生的。由于您正在学习,最好Thread.sleep在输出之间添加一些随机延迟的调用,这样您就可以希望观察到交织。

于 2013-02-11T17:15:12.267 回答
0

InSystem.out.println() out也是参考,PrintStream 因此您在两种方式中都调用相同println()的方法。

但是你得到不同的输出。虽然 println 函数有同步实现。

public void println(String x) {
    synchronized (this) {
        print(x);
        newLine();
    }
}

现在想想,outinSystem.out.println是静态的,而PrintStream out不是。

PrintStream out=new PrintStream(System.out);

在上面的声明中,新的引用out是非静态的。

如果方法不是静态的,那么添加 synchronized 关键字将同步类的实例,而不是 Class 对象。

所以为了得到你想要的结果,请PrintStream out静态

于 2015-02-11T17:13:52.023 回答