java多线程之守护线程和用户线程
2017-07-22 13:43
603 查看
Java中的线程分为两类:守护线程和用户线程,守护线程被称为后台线程、用户线程被称为前台线程。守护线程一般被用来服务用户线程,两者之间的区别就是体现在JVM的运行上,当所有的用户线程结束,JVM会自动退出,这时候系统服务停止运行,守护线程自然也只能被迫停止。反之,守护线程全部结束不一定会导致JVM退出。
守护线程和用户线程在使用上区别不大,守护线程只需要在使用时执行this.setDaemon(true)方法,且这个方法必须放在this.start()方法之前执行,否则会抛出IllegalThreadStateException异常,JDK源码中此方法上的注释也已经明确指出使用时的注意事项。
/**
* Marks this thread as either a daemon thread or a user thread. The
* Java Virtual Machine exits when the only threads running are all
* daemon threads.
* <p>
* This method must be called before the thread is started.
* <p>
* This method first calls the <code>checkAccess</code> method
* of this thread
* with no arguments. This may result in throwing a
* <code>SecurityException </code>(in the current thread).
*
* @param on if <code>true</code>, marks this thread as a
* daemon thread.
* @exception IllegalThreadStateException if this thread is active.
* @exception SecurityException if the current thread cannot modify
* this thread.
* @see #isDaemon()
* @see #checkAccess
*/
public final void setDaemon(boolean on) {
checkAccess();
if (isAlive()) {
throw new IllegalThreadStateException();
}
daemon = on;
}
下面用一个例子来比较下守护线程和用户线程的执行情况:
package com.zw;
/**
* 守护线程和用户线程
* @author Administrator
* 用户线程结束,JVM也就退出了,守护线程会立刻终止
*/
public class TestDaemon {
public static void main(String[] args) {
MyUserThread m = new MyUserThread();
MyUserThread2 m2 = new MyUserThread2();
MyDaemonThread md = new MyDaemonThread(m, m2);
md.setDaemon(true); //设置md为守护线程
md.start();
}
}
/**
* 守护线程
* @author Administrator
*
*/
class MyDaemonThread extends Thread {
MyUserThread m = null;
MyUserThread2 m2 = null;
MyDaemonThread(MyUserThread m,MyUserThread2 m2) {
this.m = m;
this.m2 = m2;
m.start();
m2.start();
}
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
while(true) {
try {
Thread.sleep(1000
4000
);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("守护线程 " + m.getI());
}
}
}
/**
* 用户线程
* @author Administrator
*
*/
class MyUserThread extends Thread {
private int i = 0;
public int getI()
{
return i;
}
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
while(i < 5) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("用户线程 " + i++);
}
}
}
class MyUserThread2 extends Thread {
private int i = 0;
public int getI()
{
return i;
}
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
while(i < 10) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("用户线程2 " + i++);
}
}
}
执行结果:
用户线程 0
用户线程2 0
守护线程 1
用户线程 1
守护线程 2
用户线程2 1
用户线程 2
守护线程 3
用户线程2 2
用户线程 3
守护线程 4
用户线程2 3
用户线程 4
守护线程 5
用户线程2 4
守护线程 5
用户线程2 5
守护线程 5
用户线程2 6
守护线程 5
用户线程2 7
守护线程 5
用户线程2 8
守护线程 5
用户线程2 9
上面的实例中启动了3个线程,一个守护线程md,两个用户线程m,m2。守护线程中无限循环执行输出,线程m执行结束时,守护线程还在自我循环中,但是当m2也结束时,守护线程也跟着停止了,这是因为m和m2两个用户线程全部结束,JVM检测到没有用户线程在执行,也就自动退出。JVM退出了,守护线程没了依托,也只能被迫停止。
Java中的GC线程就是典型的守护线程,当系统停止了对象的创建,GC没有对象可回收,就会随着JVM退出而退出。
守护线程和用户线程在使用上区别不大,守护线程只需要在使用时执行this.setDaemon(true)方法,且这个方法必须放在this.start()方法之前执行,否则会抛出IllegalThreadStateException异常,JDK源码中此方法上的注释也已经明确指出使用时的注意事项。
/**
* Marks this thread as either a daemon thread or a user thread. The
* Java Virtual Machine exits when the only threads running are all
* daemon threads.
* <p>
* This method must be called before the thread is started.
* <p>
* This method first calls the <code>checkAccess</code> method
* of this thread
* with no arguments. This may result in throwing a
* <code>SecurityException </code>(in the current thread).
*
* @param on if <code>true</code>, marks this thread as a
* daemon thread.
* @exception IllegalThreadStateException if this thread is active.
* @exception SecurityException if the current thread cannot modify
* this thread.
* @see #isDaemon()
* @see #checkAccess
*/
public final void setDaemon(boolean on) {
checkAccess();
if (isAlive()) {
throw new IllegalThreadStateException();
}
daemon = on;
}
下面用一个例子来比较下守护线程和用户线程的执行情况:
package com.zw;
/**
* 守护线程和用户线程
* @author Administrator
* 用户线程结束,JVM也就退出了,守护线程会立刻终止
*/
public class TestDaemon {
public static void main(String[] args) {
MyUserThread m = new MyUserThread();
MyUserThread2 m2 = new MyUserThread2();
MyDaemonThread md = new MyDaemonThread(m, m2);
md.setDaemon(true); //设置md为守护线程
md.start();
}
}
/**
* 守护线程
* @author Administrator
*
*/
class MyDaemonThread extends Thread {
MyUserThread m = null;
MyUserThread2 m2 = null;
MyDaemonThread(MyUserThread m,MyUserThread2 m2) {
this.m = m;
this.m2 = m2;
m.start();
m2.start();
}
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
while(true) {
try {
Thread.sleep(1000
4000
);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("守护线程 " + m.getI());
}
}
}
/**
* 用户线程
* @author Administrator
*
*/
class MyUserThread extends Thread {
private int i = 0;
public int getI()
{
return i;
}
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
while(i < 5) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("用户线程 " + i++);
}
}
}
class MyUserThread2 extends Thread {
private int i = 0;
public int getI()
{
return i;
}
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
while(i < 10) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("用户线程2 " + i++);
}
}
}
执行结果:
用户线程 0
用户线程2 0
守护线程 1
用户线程 1
守护线程 2
用户线程2 1
用户线程 2
守护线程 3
用户线程2 2
用户线程 3
守护线程 4
用户线程2 3
用户线程 4
守护线程 5
用户线程2 4
守护线程 5
用户线程2 5
守护线程 5
用户线程2 6
守护线程 5
用户线程2 7
守护线程 5
用户线程2 8
守护线程 5
用户线程2 9
上面的实例中启动了3个线程,一个守护线程md,两个用户线程m,m2。守护线程中无限循环执行输出,线程m执行结束时,守护线程还在自我循环中,但是当m2也结束时,守护线程也跟着停止了,这是因为m和m2两个用户线程全部结束,JVM检测到没有用户线程在执行,也就自动退出。JVM退出了,守护线程没了依托,也只能被迫停止。
Java中的GC线程就是典型的守护线程,当系统停止了对象的创建,GC没有对象可回收,就会随着JVM退出而退出。
相关文章推荐
- 【java多线程】用户线程和守护线程的区别
- Java多线程系列--“基础篇”10之 线程优先级和守护线程
- java多线程之守护线程Daemon()和Join()介绍
- java多线程总结二:后台线程(守护线程)
- Java多线程基础--10之 线程优先级和守护线程
- JAVA多线程编程——1.9线程让步-1.11守护线程
- Java的多线程终止,守护线程
- java多线程-守护线程
- java多线程总结二:后台线程(守护线程)
- Java 多线程之 - 守护线程 java.lang.Thread.isDaemon()方法
- 【Java 语言】Java 多线程 一 ( 线程基础 : 线程启动 | 线程停止 | 线程暂停 | 线程优先级 | 守护线程)
- Java多线程系列2(守护线程)
- JAVA.003 多线程之守护线程
- Java多线程系列--“基础篇”10之 线程优先级和守护线程
- Java多线程系列--“基础篇”10之 线程优先级和守护线程
- Java线程_守护线程和用户线程
- JAVA守护线程与用户线程的区别
- java多线程之守护线程以及Join方法
- Java多线程——守护线程
- java多线程总结二:后台线程(守护线程)