zoukankan      html  css  js  c++  java
  • Java用户线程和守护线程

      今天看Java一个关于多线程返回值方式的示例,发现一个自己不太能理解的问题,就是在主线程中启动了几个工作线程,主线程中也没有join,工作线程居然也是正常输出了回调的结果。这个跟linux C++下的线程知识可是不一样的,在C++下,如果main函数退出了,那么所有的子线程也就退出了,我一开始怀疑是不是书上写的不够仔细,没有测试,所以自己写了几个类简单的测试了一下。代码如下:

      ThreadCallback.java代码:

    package thread.callback;
    
    public class ThreadCallback {
        public void callBack(String msg) {
            System.out.println(msg);
        }
    }

      WorkThread.java代码:

    package thread.callback;
    
    public class WorkThread extends Thread{
        private ThreadCallback callback;
        private String threadName;
        public WorkThread(ThreadCallback _callback, String _threadName) {
            // TODO Auto-generated constructor stub
            this.callback = _callback;
            this.threadName = _threadName;
        }
            
        @Override
        public void run() {
            // TODO Auto-generated method stub
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            this.callback.callBack(this.threadName);
        } 
    }

      test.java代码:

    package thread.callback;
    
    public class test {
        public static void main(String[] args) {
            for (int i=0; i<5; ++i) {
                ThreadCallback callback = new ThreadCallback();
                WorkThread workThread = new WorkThread(callback, "thread" + Integer.toString(i));
                workThread.start();
                
            }
            
            System.out.println("to be end");
        }
    }

      代码非常简单啊,就是WorkThread中简单回调Callback中的接口,然后再callback中打印一下,运行的结果如下:

    to be end
    thread0
    thread2
    thread3
    thread1
    thread4

      从输出结果(thread输出顺序,每次不一定一样)可以看出来,主线程退出之后,其创建的几个子线程还是在正常运行的,直到输出了指定的结果。那么也就是跟之前linux C++下的主从线程关系不太一样了。经过搜索,发现Java线程有一个是否为守护线程的属性,默认情况下这个属性是不设置的,为false,代表这个线程是一个用户线程,如果使用Thread的setDaemon接口设置一下,那么线程属性就会变成守护线程。

      用户线程不会随着主线程退出而结束,而是会继续在JVM中运行的,直到自身结束,JVM也会等所有用户线程都执行完毕才退出。

      而守护线程会在所有用户线程(包括主线程)退出之后,一起退出,这时候JVM也就退出了。

      我们把test.java改成这样:

    package thread.callback;
    
    public class test {
    	public static void main(String[] args) {
    		for (int i=0; i<5; ++i) {
    			ThreadCallback callback = new ThreadCallback();
    			WorkThread workThread = new WorkThread(callback, "thread" + Integer.toString(i));
    			workThread.setDaemon(true);
    			workThread.start();
    			
    		}
    		
    		System.out.println("to be end");
    	}
    }

      新增setDaemon,在thread运行之前设置,然后运行程序,程序只打印"to be end"然后就退出了。

      如果我们将5个子线程中的4个设置为守护线程,一个为用户线程,会怎样呢?

      test.java代码

    package thread.callback;
    
    public class test {
    	public static void main(String[] args) {
    		for (int i=0; i<5; ++i) {
    			ThreadCallback callback = new ThreadCallback();
    			WorkThread workThread = new WorkThread(callback, "thread" + Integer.toString(i));
    			if (i != 4)
    				workThread.setDaemon(true);
    			workThread.start();
    			
    		}
    		
    		System.out.println("to be end");
    	}
    }

      那么也会可能输出所有线程结果。为啥说可能呢,这要看唯一的用户线程thread4啥时候退出了,它一退出,那么其他守护进程不管有没有执行完,都会被迫退出。在我们上面的例子中比较难出现,因为thread4是最后一个启动的,而且大家都做相同简单的事情,如果把thread4改成thread1,那么就非常容易测试出来了。

      比如我们把WorkThread.java的run改成这样:

    public void run() {
            // TODO Auto-generated method stub
            try {
                if (threadName.equals("thread4"))
                    Thread.sleep(1000);
                else
                    Thread.sleep(3000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            this.callback.callBack(this.threadName);
        } 

      那么输出结果就是:

    to be end
    thread4

      可以从上面的运行结果中看出用户线程和守护线程的区别了!

  • 相关阅读:
    POJ3421(质因数分解)
    POJ2236(并查集入门)
    POJ3111(最大化平均值)
    POJ2976(最大化平均值)
    POJ3104(二分搜索)
    POJ3258(最大化最小值)
    POJ2456(最大化最小值)
    POJ1063Cable master(二分搜索)
    Numpy模块(一)
    Django简介
  • 原文地址:https://www.cnblogs.com/chobits/p/5139860.html
Copyright © 2011-2022 走看看