多线程并发学习(四):线程中sleep,wait,notify,,notifyAll,join,yield等常用方法辨析

1. sleep()方法

使线程暂时休眠。线程的调度执行是按照优先级的高低顺序进行的,当高级线程未完成即未死亡时,低级线程没有机会获得处理器。有时候优先级高的线程需要优先级低的线程来配合它,或者优先级高的线程需要完成一些费时的操作,此时优先级高的线程应该让出处理器,使优先级低的线程有机会执行。为了达到这个目的,可以再run()方法中调用sleep()方法使自己放弃处理器资源,休眠一段时间。

参考API文档,sleep方法是一个静态方法,休眠时间长短由该方法的参数决定。
public static native void sleep(long millis) throws InterruptedException

 sleep(long)使当前线程进入停滞状态,所以执行sleep()的线程在指定的时间内肯定不会被执行; 
 sleep(long)可使优先级低的线程得到执行的机会,当然也可以让同优先级和高优先级的线程有执行的机会; 
 sleep(long)是不会释放锁标志的

使当前执行线程休眠(临时停止执行)指定的毫秒数。 线程并不失去对任何监视程序的所有权。

参数: millis - 用毫秒为单位的睡眠时间。

抛出: InterruptedException

public class InterruptTest {
    public static void main(String[] args){
       MyThread thread = new MyThread();
       thread.start();
       try{
           Thread.sleep(10000);//主线程调用sleep方法,主线程休眠
       }catch (InterruptedException e){}
       thread.interrupt();//在thread休眠时,调用该方法时将其打断。打断后,thread会抛出异常,该子线程结束
    }
}
class MyThread extends Thread{
    boolean flag = true;
    public void run(){
       while(flag){
           System.out.println("=="+new Date()+"==");
           try{ //在此处必须使用try-catch,由于sleep已经抛出异常,此处也必须处理异常。但                是并不能写成 public void run() throws InterruptedException。因为run方法为重写方法,重写方法不能抛出和被重写方法不同的异常。
              sleep(1000);//每隔1秒钟打印一次系统时间
           }catch (InterruptedException e){
              return; 
           }
       }
    }
}

2. wait()方法和notify()、notifyAll() 

wait()方法的作用:让该线程处于等待状态。

notify()方法的作用:唤醒处于wait的线程。

notifyAll()方法的作用:唤醒所有处于wait状态的线程。

 这三个方法用于协调多个线程对共享数据的存取,所以必须在Synchronized语句块内使用这三个方法。Synchronized这个关键字用于保护共享数据,阻止其他线程对共享数据的存取。但是这样程序的流程就很不灵活了,如何才能在当前线程还没退出Synchronized数据块时让其他线程也有机会访问共享数据呢?此时就用这三个方法来灵活控制。 
wait()方法使当前线程暂停执行并释放对象锁标志,让其他线程可以进入Synchronized数据块,当前线程被放入对象等待池中。当调用 notify()方法后,将从对象的等待池中移走一个任意的线程并放到锁标志等待池中,只有锁标志等待池中的线程能够获取锁标志;如果锁标志等待池中没有线程,则notify()不起作用。 
notifyAll()则从对象等待池中移走所有等待那个对象的线程并放到锁标志等待池中。 
注意 这三个方法都是java.lang.Ojbect的方法! 

3. run()和start()

把需要并行处理的代码放在run()方法中,start()方法启动线程将自动调用 run()方法,这是由Java的内存机制规定的。并且run()方法必须是public访问权限,返回值类型为void

4. join()方法

她是合并某个线程的方法。把一个线程合并到正在执行的线程当中。合并后,当前线程等待合进来的线程先执行完成后继续执行。

实例:测试现象为合并后子线程先执行,结束后主线程开始执行

public class JoinTest {
    public static void main(String[] args) {
       NewThread t = new NewThread("t thread"); //[1]创建一个名为“t thread”的子线程
       t.start();
       try { //[2]join和sleep一样,也抛出异常,所以同样的处理方法
           t.join();//[3]把子线程合并到主线程中来,此刻先执行子线程后执行主线程
       }catch (InterruptedException e) {} 
       for(int i=1;i<=5;i++){
           System.out.println("This is main thread");
        }
    }   
}
class NewThread extends Thread {
    NewThread(String s) { //[4]给线程命名的方法,具体参考API文档。
       super(s);
    }
    public void run() {
       for(int i = 1;i<=5;i++) {
           System.out.println("This is "+getName());
           try {
              sleep(1000);
           }catch (InterruptedException e) {
              return;
           }
       }
    }
}

5. yield()方法

她是一种让出CPU,给其他线程执行的方法。

实例:定义两个子线程,每当满足条件时,让出线程给对方执行

public class YieldTest {
    public static void main(String[] args){
       NewThread1 t1 = new NewThread1("t1");
       NewThread1 t2 = new NewThread1("t2");
       t1.start(); 
       t2.start();
    }
}
class NewThread1 extends Thread{
    NewThread1(Strings){
       super(s);
    }
    public void run() {
       for(int i=1;i<=100;i++){
       System.out.println(getName()+":"+i);
       if(i==0){
           yield();
        }
       }
    }
}

 

参考:https://blog.csdn.net/tongxuexie/article/details/80145663

           https://blog.csdn.net/tongxuexie/article/details/80175330

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值