Java 线程如何知道前面有一个连接方法
下面是我的示例代码,当调用我的Java 线程如何知道前面有一个连接方法,java,multithreading,pthread-join,Java,Multithreading,Pthread Join,下面是我的示例代码,当调用我的a.start()时,它应该创建一个线程并立即打印“Run”。但为什么打印后被称为“开始”20次 线程“a”如何决定它不必立即调用run() public class JoinTest implements Runnable { public static void main(String[] args) throws InterruptedException { Thread a = new Thread(new JoinTest());
a.start()
时,它应该创建一个线程并立即打印“Run”。但为什么打印后被称为“开始”20次
线程“a”如何决定它不必立即调用run()
public class JoinTest implements Runnable {
public static void main(String[] args) throws InterruptedException {
Thread a = new Thread(new JoinTest());
a.start();
for (int i = 0; i < 20; i++) {
System.out.print("Begin");
}
Thread.sleep(1000);
a.join();
System.out.print("\nEnd");
}
public void run() {
System.out.print("\nRun");
}
}
我对线程的行为有点困惑
在我看来,
“run”
应该在“begin”
之前打印,因为它是在调用join()
方法之前打印的,在调用join方法时,名为thread“a”的方法必须已完成其执行,此时调用join肯定是无用的。您启动线程,然后立即进行一些打印,然后睡觉。查看您的代码时,我实际上希望看到Begin
在Run
之前,因为线程是在后台启动的,与主线程同时进行工作。此外,print
方法是同步的,因此您可以在循环中重复获取该锁,从而减少第二个线程插入的机会
我已使用线程尝试了您的代码。睡眠已消除,无论是否使用加入调用。这两种情况下的行为都是相同的:Run
大部分时间在末尾出现,偶尔会在Begin
单词之间交错出现。一切都完全符合使用同步块的简单并发模型的预期
下面是代码的一个细微变化,它可以可靠地打印Run
,而不管您是否调用join
方法。所有的改变都是sleep
调用的位置
public class JoinTest implements Runnable
{
public static void main(String[] args) throws InterruptedException {
Thread a = new Thread(new JoinTest());
a.start();
Thread.sleep(1000);
for (int i = 0; i < 20; i++) {
System.out.print("Begin");
}
a.join();
System.out.print("\nEnd");
}
public void run() {
System.out.print("\nRun");
}
}
公共类JoinTest实现可运行
{
公共静态void main(字符串[]args)引发InterruptedException{
线程a=新线程(新JoinTest());
a、 start();
睡眠(1000);
对于(int i=0;i<20;i++){
系统输出打印(“开始”);
}
a、 join();
系统输出打印(“\nEnd”);
}
公开募捐{
系统输出打印(“\n运行”);
}
}
启动线程,然后立即进行打印,然后进入睡眠状态。查看您的代码时,我实际上希望看到Begin
在Run
之前,因为线程是在后台启动的,与主线程同时进行工作。此外,print
方法是同步的,因此您可以在循环中重复获取该锁,从而减少第二个线程插入的机会
我已使用线程尝试了您的代码。睡眠已消除,无论是否使用加入调用。这两种情况下的行为都是相同的:Run
大部分时间在末尾出现,偶尔会在Begin
单词之间交错出现。一切都完全符合使用同步块的简单并发模型的预期
下面是代码的一个细微变化,它可以可靠地打印Run
,而不管您是否调用join
方法。所有的改变都是sleep
调用的位置
public class JoinTest implements Runnable
{
public static void main(String[] args) throws InterruptedException {
Thread a = new Thread(new JoinTest());
a.start();
Thread.sleep(1000);
for (int i = 0; i < 20; i++) {
System.out.print("Begin");
}
a.join();
System.out.print("\nEnd");
}
public void run() {
System.out.print("\nRun");
}
}
公共类JoinTest实现可运行
{
公共静态void main(字符串[]args)引发InterruptedException{
线程a=新线程(新JoinTest());
a、 start();
睡眠(1000);
对于(int i=0;i<20;i++){
系统输出打印(“开始”);
}
a、 join();
系统输出打印(“\nEnd”);
}
公开募捐{
系统输出打印(“\n运行”);
}
}
在线程上调用start()
不一定会立即触发其run()
方法的执行。您的线程被标记为已启动,但主线程在for
循环中继续执行。一旦主线程到达sleep()
语句,JVM就会切换到您的线程。在线程上调用start()
不一定会立即触发其run()
方法的执行。您的线程被标记为已启动,但主线程在for
循环中继续执行。然后,当主线程到达sleep()
语句时,JVM将切换到您的线程。方法调用线程的run()
方法,尽管这需要一点时间,这可能足以让部分或所有“Begin”循环完成。当我在我的机器上运行时,“运行”输出出现在第一个和第二个“开始”之间。尝试使用时间戳输出,以便查看机器执行每个命令所需的时间:
public class JoinTest implements Runnable {
public static void main(String[] args) throws InterruptedException {
Thread a = new Thread(new JoinTest());
a.start();
for (int i = 0; i < 20; i++) {
System.out.println("Begin " + System.nanoTime());
}
Thread.sleep(1000);
a.join();
System.out.println("End " + System.nanoTime());
}
public void run() {
System.out.println("Run " + System.nanoTime());
}
}
公共类JoinTest实现可运行{
公共静态void main(字符串[]args)引发InterruptedException{
线程a=新线程(新JoinTest());
a、 start();
对于(int i=0;i<20;i++){
System.out.println(“Begin”+System.nanoTime());
}
睡眠(1000);
a、 join();
System.out.println(“End”+System.nanoTime());
}
公开募捐{
System.out.println(“Run”+System.nanoTime());
}
}
此时调用a.join()
可以确保在“End”之前始终看到“Run”输出,因为join()方法调用线程的Run()
方法,尽管这需要一点时间,这可能只够完成部分或全部“Begin”循环。当我在我的机器上运行时,“运行”输出出现在第一个和第二个“开始”之间。尝试使用时间戳输出,以便查看机器执行每个命令所需的时间:
public class JoinTest implements Runnable {
public static void main(String[] args) throws InterruptedException {
Thread a = new Thread(new JoinTest());
a.start();
for (int i = 0; i < 20; i++) {
System.out.println("Begin " + System.nanoTime());
}
Thread.sleep(1000);
a.join();
System.out.println("End " + System.nanoTime());
}
public void run() {
System.out.println("Run " + System.nanoTime());
}
}
公共类JoinTest实现可运行{
公共静态void main(字符串[]args)引发InterruptedException{
线程a=新线程(新JoinTest());
a、 start();
对于(int i=0;i<20;i++){
System.out.println(“Begin”+System.nanoTime());
}