Java 干扰线程
我在理解这段代码时遇到了一个问题,我的问题是为什么这两个线程在执行Java 干扰线程,java,multithreading,Java,Multithreading,我在理解这段代码时遇到了一个问题,我的问题是为什么这两个线程在执行run方法中的语句时不会相互干扰 我的意思是,所有的语句都是先执行,然后再执行第二个线程 第一个线程执行语句的一部分,然后第二个线程执行语句的一部分,然后第一个线程继续其任务是不可能的 注意:我知道这两个线程使用不同的OutputStream对象 这里的线程代码 class Printer extends Thread { private String ThreadName; public Printer(Strin
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();
}
}
试着用
out
替换System.out
,并比较结果,然后你就会确切地知道我要的是什么在解释之前有几件事:
不需要扩展线程
,只需实现可运行
,它提供了您正在实现的运行
方法,就更容易了。此时,您可以将Runnable
分配给线程
,或者更有用的是,分配给执行器(对于Java中的多线程非常有用)
此外,在PrintStream
中包装也是多余的,因为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
这并不是因为有什么东西坏了,而是因为线程执行得太快了,所以就这样发生了。由于您正在学习,因此最好在输出之间添加一些线程。随机延迟的sleep
调用,以便您能够有希望地观察交织情况。在解释之前有几件事:
不需要扩展线程
,只需实现可运行
,它提供了您正在实现的运行
方法,就更容易了。此时,您可以将Runnable
分配给线程
,或者更有用的是,分配给执行器(对于Java中的多线程非常有用)
此外,在PrintStream
中包装也是多余的,因为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
这并不是因为有什么东西坏了,而是因为线程执行得太快了,所以就这样发生了。由于您正在学习,最好在输出之间添加一些线程。睡眠随机延迟调用,这样您就可以有希望地观察到交织。inSystem.out.println()
out
也是PrintStream
因此,您以两种方式调用相同的println()
但你得到的是不同的输出。虽然println函数有同步实现
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}
现在想想,System.out.println
中的out
是静态的,而PrintStream out
不是
PrintStream out=new PrintStream(System.out);
在上面的语句中,out
的新引用是非静态的
如果方法不是静态的,那么添加synchronized关键字将
同步类的实例,而不是类对象
因此,为了获得所需的结果,在System.out.println()中制作PrintStream out
static,out
也是PrintStream
因此,您以两种方式调用相同的println()
但你得到的是不同的输出。虽然println函数有同步实现
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}
现在想想,System.out.println
中的out
是静态的,而PrintStream out
不是
PrintStream out=new PrintStream(System.out);
在上面的语句中,out
的新引用是非静态的
如果方法不是静态的,那么添加synchronized关键字将
同步类的实例,而不是类对象
因此,为了得到您想要的结果,请整理一下您的代码样本。到目前为止,您有研究过什么吗?您发现了什么?当您运行它们时,它们不会干扰这一事实并不意味着它们通常不会干扰(例如,在另一台计算机上运行,在不同的情况下运行等)。当我运行代码时,当打印另一个线程的输出时,第一个线程的输出通常在换行之前“暂停”。当重复运行程序时,每次都会得到不同的输出。我对答案的最佳猜测是“因为调度程序就是这样选择运行它们的”。这可能还与他们都试图阻止相同的资源(System.out
)有关,我认为这可能是同步的你应该得到你期望的行为(如果没有增加到100000)。您的运行可能完成得太快,第二个线程还没有时间启动。请清理您的代码示例。到目前为止,您研究过任何内容吗?你发现了什么?事实上他们没有