Daemon线程和Join线程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fightfaith/article/details/50999450

1、Daemon线程


  Daemon线程称为守护线程(非常喜欢这个名字)。线程一旦被设置为守护线程,当非守护线程结束,守护线程即使没有执行完,也必须随之全部结束。例如我们曾经玩儿过的坦克大战,一旦守护的老巢完蛋了,其它守护坦克没死也要结束。

  Daemon线程的实质作用是为主线程其他线程的运行提供服务。User Thread线程和Daemon Thread守护线程本质上来说去没啥区别的,唯一的区别之处就在虚拟机的离开:如果User Thread全部撤离,那么Daemon Thread也就没啥线程好服务的了,所以虚拟机也就退出了。

  设定守护线程方法:public final void setDaemon(boolean on) ;但是有几点需要注意:

    thread.setDaemon(true)必须在thread.start()之前设置,否则会抛出IllegalThreadStateException异常。因为我们不能够将正在运行的常规线程设为守护线程。

    在Daemon线程中产生的新线程也是Daemon的。

    不是所有的应用都可以分配给Daemon线程来进行服务,比如读写操作或者计算逻辑。我们必须防止在Daemon Thread还没来的及进行操作时,虚拟机可能已经退出了。


2、Daemon实例


  (1)待设置为Daemon线程的线程类


<span style="font-size:18px;">//实现Runnable接口
public class DaemonDemo implements Runnable {
	
	//重写run方法
	@Override
	public void run() {
		for (int x = 0; x < 1000; x++) {
			System.out.println(Thread.currentThread().getName() + "---" + x);
		}
	}
}</span>

  (2)测试类


<span style="font-size:18px;">public class DaemonDemoTest {
	public static void main(String[] args) {
		DaemonDemo dd = new DaemonDemo();

		Thread t1 = new Thread(dd);
		Thread t2 = new Thread(dd);
		
		//将t1、t2设置为守护线程,注意要在start()方法调用之前设置
		t1.setDaemon(true);
		t2.setDaemon(true);

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

		for (int x = 0; x < 10; x++) {
			System.out.println(Thread.currentThread().getName() + "---" + x);
		}
	}
}</span>

  运行结果:main线程中的10次循环结束时,两个没有执行结束的守护线程都会随之结束。


3、Join线程


  当线程被调用了Join()方法,那么其它线程必须等待,直到本线程结束,其它线程才能执行。Join在英文中解释为合并、加入,我更喜欢称之为阻塞线程,程序必须首先执行完阻塞线程才能够去执行其他线程。

  Join线程的作用:在很多情况下,主线程生成并起动了子线程,如果子线程里要进行大量的耗时的运算,主线程往往将于子线程之前结束(正如我们上面的例子),但是如果主线程处理完其他的事务后,需要用到子线程的处理结果,也就是主线程需要等待子线程执行完成之后再结束,这个时候就要用到join()方法了。


4、Join线程实例


  (1)待设置线程类


<span style="font-size:18px;">public class JoinDemo implements Runnable {

	@Override
	public void run() {
		for (int x = 0; x < 100; x++) {
			System.out.println(Thread.currentThread().getName() + "---" + x);
		}
	}
}</span>

  (2)测试类


<span style="font-size:18px;">public class JoinDemoTest {
	public static void main(String[] args) {
		PriorityDemo pd = new PriorityDemo();

		Thread t1 = new Thread(pd);
		Thread t2 = new Thread(pd);
		Thread t3 = new Thread(pd);

		t1.setName("线程一");
		t2.setName("线程二");
		t3.setName("线程三");

		t2.start();
		// join()线程 加入线程
		try {
			t2.join(); //必须首先将t2执行完毕才能去执行其它线程
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		t1.start();
		t3.start();
	}
}</span>

  运行结果:首先结束t2线程之后才会执行t1和t3线程。




猜你喜欢

转载自blog.csdn.net/fightfaith/article/details/50999450