多线程学习(六)线程的调度-让步&合并&守护线程

转载 2016年06月01日 10:02:59

转自:http://lavasoft.blog.51cto.com/62575/221811

Java线程:线程的调度-让步

线程的让步含义就是使当前运行着线程让出CPU资源,但是然给谁不知道,仅仅是让出,线程状态回到可运行状态。 
线程的让步使用Thread.yield()方法,yield() 为静态方法,功能是暂停当前正在执行的线程对象,并执行其他线程。
 
/** 
* Java线程:线程的调度-让步 

* @author leizhimin 2009-11-4 9:02:40 
*/
 
public class Test { 
        public static void main(String[] args) { 
                Thread t1 = new MyThread1(); 
                Thread t2 = new Thread(new MyRunnable()); 

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


class MyThread1 extends Thread { 
        public void run() { 
                for (int i = 0; i < 10; i++) { 
                        System.out.println("线程1第" + i + "次执行!"); 
                } 
        } 


class MyRunnable implements Runnable { 
        public void run() { 
                for (int i = 0; i < 10; i++) { 
                        System.out.println("线程2第" + i + "次执行!"); 
                        Thread.yield(); 
                } 
        } 
}
 
线程2第0次执行! 
线程2第1次执行! 
线程2第2次执行! 
线程2第3次执行! 
线程1第0次执行! 
线程1第1次执行! 
线程1第2次执行! 
线程1第3次执行! 
线程1第4次执行! 
线程1第5次执行! 
线程1第6次执行! 
线程1第7次执行! 
线程1第8次执行! 
线程1第9次执行! 
线程2第4次执行! 
线程2第5次执行! 
线程2第6次执行! 
线程2第7次执行! 
线程2第8次执行! 
线程2第9次执行! 

Process finished with exit code 0


问题解答:

Q:为什么线程2被执行了4次才让出呢?不是第一次就让出呢?

A:要给电脑反应的时间啊!在执行yield的时候的时间段 电脑还在那边同步线程2输出呢,执行完了yield()时候才开始停止 2线 开始1线!


Java线程:线程的调度-合并

线程的合并的含义就是将几个并行线程的线程合并为一个单线程执行,应用场景是当一个线程必须等待另一个线程执行完毕才能执行时可以使用join方法。 
join为非静态方法,定义如下:
void join()    
    等待该线程终止。    
void join(long millis)    
    等待该线程终止的时间最长为 millis 毫秒。    
void join(long millis, int nanos)    
    等待该线程终止的时间最长为 millis 毫秒 + nanos 纳秒。
 
/** 
* Java线程:线程的调度-合并 

* @author leizhimin 2009-11-4 9:02:40 
*/
 
public class Test { 
        public static void main(String[] args) { 
                Thread t1 = new MyThread1(); 
                t1.start(); 

                for (int i = 0; i < 20; i++) { 
                        System.out.println("主线程第" + i + "次执行!"); 
                        if (i > 2) try { 
                                //t1线程合并到主线程中,主线程停止执行过程,转而执行t1线程,直到t1执行完毕后继续。
                                t1.join(); 
                        } catch (InterruptedException e) { 
                                e.printStackTrace(); 
                        } 
                } 
        } 


class MyThread1 extends Thread { 
        public void run() { 
                for (int i = 0; i < 10; i++) { 
                        System.out.println("线程1第" + i + "次执行!"); 
                } 
        } 
}
 
主线程第0次执行! 
主线程第1次执行! 
主线程第2次执行! 
线程1第0次执行! 
主线程第3次执行! 
线程1第1次执行! 
线程1第2次执行! 
线程1第3次执行! 
线程1第4次执行! 
线程1第5次执行! 
线程1第6次执行! 
线程1第7次执行! 
线程1第8次执行! 
线程1第9次执行! 
主线程第4次执行! 
主线程第5次执行! 
主线程第6次执行! 
主线程第7次执行! 
主线程第8次执行! 
主线程第9次执行! 
主线程第10次执行! 
主线程第11次执行! 
主线程第12次执行! 
主线程第13次执行! 
主线程第14次执行! 
主线程第15次执行! 
主线程第16次执行! 
主线程第17次执行! 
主线程第18次执行! 
主线程第19次执行! 

Java线程:线程的调度-守护线程

守护线程与普通线程写法上基本么啥区别,调用线程对象的方法setDaemon(true),则可以将其设置为守护线程。
守护线程使用的情况较少,但并非无用,举例来说,JVM的垃圾回收、内存管理等线程都是守护线程。还有就是在做数据库应用时候,使用的数据库连接池,连接池本身也包含着很多后台线程,监控连接个数、超时时间、状态等等。
 
setDaemon方法的详细说明:
public final void setDaemon(boolean on)将该线程标记为守护线程或用户线程。当正在运行的线程都是守护线程时,Java 虚拟机退出。    
  该方法必须在启动线程前调用。    

  该方法首先调用该线程的 checkAccess 方法,且不带任何参数。这可能抛出 SecurityException(在当前线程中)。    


  参数: 
    on - 如果为 true,则将该线程标记为守护线程。    
  抛出:    
    IllegalThreadStateException - 如果该线程处于活动状态。    
    SecurityException - 如果当前线程无法修改该线程。 
  另请参见: 
    isDaemon(), checkAccess()

 
/** 
* Java线程:线程的调度-守护线程 

* @author leizhimin 2009-11-4 9:02:40 
*/
 
public class Test { 
        public static void main(String[] args) { 
                Thread t1 = new MyCommon(); 
                Thread t2 = new Thread(new MyDaemon()); 
                t2.setDaemon(true);        //设置为守护线程 

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


class MyCommon extends Thread { 
        public void run() { 
                for (int i = 0; i < 5; i++) { 
                        System.out.println("线程1第" + i + "次执行!"); 
                        try { 
                                Thread.sleep(7); 
                        } catch (InterruptedException e) { 
                                e.printStackTrace(); 
                        } 
                } 
        } 


class MyDaemon implements Runnable { 
        public void run() { 
                for (long i = 0; i < 9999999L; i++) { 
                        System.out.println("后台线程第" + i + "次执行!"); 
                        try { 
                                Thread.sleep(7); 
                        } catch (InterruptedException e) { 
                                e.printStackTrace(); 
                        } 
                } 
        } 
}
 
后台线程第0次执行! 
线程1第0次执行! 
线程1第1次执行! 
后台线程第1次执行! 
后台线程第2次执行! 
线程1第2次执行! 
线程1第3次执行! 
后台线程第3次执行! 
线程1第4次执行! 
后台线程第4次执行! 
后台线程第5次执行! 
后台线程第6次执行! 
后台线程第7次执行! 

 
从上面的执行结果可以看出:
前台线程是保证执行完毕的,后台线程还没有执行完毕就退出了。
 
实际上:JRE判断程序是否执行结束的标准是所有的前台执线程行完毕了,而不管后台线程的状态,因此,在使用后台线程时候一定要注意这个问题。



多线程(三)线程控制之线程让步

yield()方法是一个和sleep()方法有点类似的方法,它也是Thread类提供的一个静态方法,它可以让当前正在执行的线程暂停,但它不会阻塞该线程,它只是将该线程转入就绪状态。yield()只是让...
  • hi_gebilaowang
  • hi_gebilaowang
  • 2016年08月14日 12:43
  • 526

线程学习笔记(五)-线程让步和线程守护

在《Java范例大全》这本书上,线程让步和线程守护是分为两个例子来讲的,但是线程让步和线程守护都在讲一个等字,我认为它们两个可以合到一个程序里面来看现象。另外这本书上关于守护线程的例子有问题。 (1)...
  • sdtvyyb_007
  • sdtvyyb_007
  • 2017年08月10日 15:37
  • 82

Python3多线程--守护线程&非守护线程

1、说明:设置一个线程是守护线程,就说明这不是一个很重要的线程,对于这样的线程,只要主线程运行结束,就会直接退出。而如果一个线程不是守护线程的话,即使主线程运行结束也不会退出,而是等待所有的非守护线程...
  • gaitiangai
  • gaitiangai
  • 2017年02月27日 15:07
  • 396

python 多线程中的守护线程与join的用法

多线程:在同一个时间做多件事 守护线程:如果在程序中将子线程设置为守护线程,则该子线程会在主线程结束时自动退出,设置方式为thread.setDaemon(True),要在thread.start(...
  • thn_sweety
  • thn_sweety
  • 2016年12月09日 15:42
  • 2472

Java守护线程和main线程整理

Java中有两类线程:User Thread(用户线程)、Daemon Thread(守护线程) 用个比较通俗的比如,任何一个守护线程都是整个JVM中所有非守护线程的保姆:只要当前JVM实例中尚存...
  • qq_33098039
  • qq_33098039
  • 2017年10月09日 09:40
  • 381

线程的调度-让步

线程的让步含义就是使当前运行着线程让出CPU资源,但是然给谁不知道,仅仅是让出,线程状态回到可运行状态。   线程的让步使用Thread.yield()方法,yield() 为静态方法,功...
  • gaokewoo
  • gaokewoo
  • 2014年04月30日 16:08
  • 209

一篇博文彻底了解线程的调度策略

线程的调度策略 在java的线程开发中,线程的调度策略是一个很重要的知识点,起承上启下的作用,所以我们下面去一起看看系统是怎么安排线程之间的运行规则的。 线程调度的目的 首先我们要知道,...
  • farley119
  • farley119
  • 2016年12月04日 22:19
  • 1472

Java的多线程终止,守护线程

Java中线程分为两种类型:用户线程和守护(服务)线程。通过Thread.setDaemon(false)设置为用户线程;通过Thread.setDaemon(true)设置为守护线程;不设置则默认为...
  • never_tears
  • never_tears
  • 2017年03月16日 21:51
  • 742

守护线程与普通线程

守护线程与普通线程的唯一区别是:当JVM中所有的线程都是守护线程的时候,JVM就可以退出了;如果还有一个或以上的非守护线程则不会退出。(以上是针对正常退出,调用System.exit则必定会退出)  ...
  • DENGZHUYU
  • DENGZHUYU
  • 2015年05月18日 21:54
  • 1230

C++多线程实例(线程的建立—调度—正确结束)

C++中的多线程编程时一个非常复杂的东西,使用过程中一定要注意线程的调度和结束。那么为什么要用多线程呢?举一个例子,界面里有个按钮,按钮按下后,这个操作需要非常长的时间才能完成,那么在操作未完成之前,...
  • niusiqiang
  • niusiqiang
  • 2014年08月10日 13:28
  • 1122
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:多线程学习(六)线程的调度-让步&合并&守护线程
举报原因:
原因补充:

(最多只允许输入30个字)