主方法关闭后如何运行线程?

时间:2014-03-03 12:31:48

标签: java multithreading

以下是我的两个课程:

public class Firstclass {
    public static void main(String args[]) throws InterruptedException {
        System.out.println("Main start....");
        Secondclass t1 = new Secondclass();
        t1.setName("First Thread");
        Secondclass t2 = new Secondclass();
        t2.setName("Second Thread");
        t1.start();
        t2.start();
        System.out.println("Main close...");
    }
}

public class Secondclass extends Thread {
    @Override
    public void run() {
        try {
            loop();
        } catch(Exception e) {
            System.out.println("exception is" + e);
        }
    }

    public void loop() throws InterruptedException {
        for(int i = 0; i <= 10; i++) {
            Thread t = Thread.currentThread();
            String threadname = t.getName();
            if(threadname.equals("First Thread")) {
                Thread.sleep(1000);
            } else {
                Thread.sleep(1500);
            }
            System.out.println("i==" + i);   
        }
    }
}

现在,当我运行Firstclass时,输出为:

Main start....
Main close...
i==0
i==0
i==1
i==1
i==2
i==3
i==2
i==4
i==3
i==5
i==6
i==4
i==7
i==5
i==8
i==9
i==6
i==10
i==7
i==8
i==9
i==10

我的第一个问题是:我想知道为什么即使main方法已经完成,两个线程仍在运行?

我的第二个问题是:任何人都可以向我解释方法joinsynchronized之间的区别是什么?

6 个答案:

答案 0 :(得分:3)

  

我想知道即使主要方法已关闭,两者如何   线程还在运行吗?

一旦最后一个非jvm线程终止,JVM将退出。这意味着如果您创建的任何线程仍在运行,则jvm将不会关闭。守护程序线程是不阻止JVM关闭的线程。通常你会将它们用于某些后台任务,如果用户要求它关闭,你不希望保留你的应用程序。

守护程序线程是一个线程,当程序完成但线程仍在运行时,它不会阻止JVM退出。守护程序线程的一个示例是垃圾收集。

您可以使用setDaemon()方法更改Thread守护程序属性。默认情况下,除非您明确调用setDaemon()方法,否则用户创建的每个线程都是普通(非守护程序)线程。

  

解释我和join方法有什么区别   同步

同步是一种锁定机制,允许两个线程不相互踩,即同步用于在多个线程的帮助下提供对共享资源的正确访问锁定机制。
另一方面,join()方法调用允许一个线程等待另一个线程的完成。

答案 1 :(得分:3)

你的第一个问题,

默认情况下调用main方法时会创建一个主线程。主线程是非dameon线程。当main方法创建的线程继承它的parant的属性时。这意味着它们都是非守护程序线程。如您所知,JVM会等待所有非守护程序线程完成。所以即使在主线程完成后它也会执行。

见这里: daemon vs non-daemon Java Stack for each thread creation

和你的第二个问题: join方法在调用join方法的线程末尾加入当前运行的线程。这意味着当前线程将被停止,并在join方法引用的线程之后启动。

同步会停止两个线程同时执行相同的代码。

答案 2 :(得分:2)

  

我想知道即使主要方法已关闭,两者如何   线程还在运行吗?

您的main()方法由一个单独的线程运行,该线程启动另外两个线程(First ad Second)。所有线程都不相互依赖,因此,主线程可以打印其他线程起始行下面的行。

  

我的第二个问题是,任何人都可以解释我有什么区别   在join方法和synchronized之间?

join()表示等待线程完成。这是一种阻止方法。 synchronized是一个关键字,表示多线程无法同步访问同步的块/方法。

答案 3 :(得分:2)

<强>加入 如果你有一个线程B在另一个线程A完成其工作之前无法完成它的工作,那么你希望线程B“加入”线程A.

<强>同步 当我们使用线程时,我们通常需要在某处使用某些同步 确保我们的方法不会在错误的时间互相打断并弄乱我们的方法 数据。通常,任何时候多个线程访问可变(可更改) 数据,您同步以保护该数据,以确保两个线程不会更改 它同时(或者一个不同时改变另一个) 阅读它,这也令人困惑)。

答案 4 :(得分:2)

用户和守护程序有两种类型的线程。因此,如果您希望程序退出,请将您的线程作为守护程序。

实施例

Thread t = new Thread();
t.setDaemon(true);

当没有更多用户线程时,进程终止。

到第二个问题:

加入仅在您需要确保线程死亡时使用那之后你无事可做

同步用于线程间通信

答案 5 :(得分:1)

您的main主题未关闭 -

      // ...
      System.out.println("Main close...");
      // <--- Your main method is here while all the other threads complete (sort of).
     }

问题的第2部分 - joinsynchronized之间没有任何关联。他们几乎相反。

  • join - 在恢复之前等待线程完成。
  • synchronized - 只有一个线程可以进入此处,其他所有人都必须等待。