控制线程之join、sleep、yeild、线程的优先级

join线程:当某个程序执行流中调用其他线程的join()方法时,调用线程将被阻塞,直到被join方法加入的join线程完成为止。


public class Test2 {
 public static void main(String[] args) throws InterruptedException {
 Join j1=new Join("新线程");
 j1.start();
 for (int i = 0; i <100; i++) {
  if(i==20){
   Join j2=new Join("被Join的线程");
   j2.start();
   j2.join();
  }
  System.out.println(Thread.currentThread().getName()+" "+i);
 }}
class Join extends Thread{
 String name;
 public Join(String name){
  this.name=name;}
 public void run(){
  for (int i = 0; i <100; i++) {
   System.out.println(getName()+" "+i);} }}
结果如图:


    主方法开始时就启动了名为“新线程”的子线程,该子线程将会和main线程并发执行当i=20时,名为“被join的线程”启动,该线程不会和main线程并发执行,main必须等该线程执行结束后才可以向下执行。


join()方法有三种重载形式:
1、等待被join的线程执行完成
2、join(long millis):等待被join的线程的时间最长为millis毫秒。如果在millis内被join的线程还没执行结束则不再等待。
3、join(long millis,int nanos)等待被join的线程的时间最长为millis毫秒加nanos微妙。

 

 

后台线程:在后台运行的线程,它的任务是为其他的线程提供服务。如果所有的前台线程都死亡了,后台线程会自动死亡,因为当整个虚拟机中只剩下后台线程时,程序就没有继续运行的必要了,所以虚拟机也就退出了。调用Thread对象的setDaemon(true)方法可将指定线程设置成后台线程。

 

public class Test2 {
 public static void main(String[] args) throws InterruptedException {
 Daemon d1=new Daemon();
 d1.setDaemon(true);//将此线程设置成后台线程
 d1.start();//启动后台线程
 for (int i = 0; i <100; i++) {
  System.out.println(Thread.currentThread().getName()+" "+i);
 }//程序执行好此处,前台线程 main结束,后台线程也随之结束

 } }
class Daemon extends Thread{
  public void run(){
  for (int i = 0; i <100; i++) {
   System.out.println(getName()+" "+i);
 }}}


    Thread中的isDaemon()方法,用于判断指定线程是否为后台线程。如要将某个线程设置为后台线程,必须在该线程启动之前设置,即setDaemon(true)必须在start()之前。

 

 

线程睡眠sleep:让当前正在执行的线程暂停一段时间并进入阻塞状态

 


线程让步yield:与sleep有点相似,也可以让正在执行的线程暂停,但它不会阻塞该线程,它只是将该线程转入就绪状态。当调用了yield方法后,只有优先级与当前线程相同,或者优先级比当前线程更高的就绪状态的线程才会获得执行的机会
public class Test2 {
 public static void main(String[] args) {
  Yield y1=new Yield("高级");
  Yield y2=new Yield("低级");
//  y1.setPriority(Thread.MAX_PRIORITY);
  y1.start();
//  y2.setPriority(Thread.MIN_PRIORITY);
  y2.start();}
class Yield extends Thread{
 public Yield(){}
 public Yield(String name){
  super(name);
 }
 public void run(){
  for (int i = 0; i <100; i++) {
   System.out.println(getName()+" "+i);
   if(i==20){//当i=20时,使用yield方法让当前线程让步
    Thread.yield();
   } }}}
结果如图:


sleep与yield方法的区别:
1、sleep方法暂停当前线程后,会给其他线程执行机会i,不会理会其他线程的优先级,但yield方法只会给优先级相同或优先级更高的线程执行机会。
2、sleep会将线程转入阻塞状态,直到经过阻塞时间才会转入就绪状态,而yield只是强制当前线程进入就绪状态,因此有可能某个线程调用yield方法暂停后,立即再次获得处理器资源被执行。
3、sleep方法声明抛出了InterruptedException异常,所以调用sleep时要捕获异常,而yield不用。
4、sleep比yield有更好的可移植性。

 

 

改变线程的优先级:
每个线程的默认优先级都与创建它的父线程具有相同的优先级。main函数的默认优先级为普通优先级。
Thread提供了setPriority()和getPriority()方法来设置和返回指定线程的优先级,其中setPriority方法的参数可以是一个整数(1~10),也可以是Thread类的三个静态常量:MAX_PRIORITY(值为10)、MIN_PRIORITY(值为1)、NORM_PRIORITY(值为5)。

 

posted @ 2012-02-21 18:57  广东仔-学习ing  阅读(1784)  评论(0编辑  收藏  举报