java多线程 sleep()和wait()的使用和区别

Thread.sleep(long millis)和Thread.sleep(long millis, int nanos)静态方法强制当前正在执行的线程休眠(暂停执行),以“减慢线程”。
当线程睡眠时,它睡在某个地方,在苏醒之前不会返回到可运行状态。
当睡眠时间到期,则返回到可运行状态。
线程睡眠的原因:线程执行太快,或者需要强制进入下一轮,因为Java规范不保证合理的轮换。
睡眠的实现:调用静态方法。
 

       try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace(); 
        }


 
睡眠的位置:为了让其他线程有机会执行,可以将Thread.sleep()的调用放线程run()之内。这样才能保证该线程执行过程中会睡眠。
public class TestSleep {
 
  public static void main(String[] args) {
   
    MyThread2 t1 = new MyThread2("TestSleep");
    t1.start();
      
     for(int i=0 ; i <10; i++)
              System.out.println("I am Main Thread");
   }
 }
 
 class MyThread2 extends Thread {
  
    MyThread2(String s) {
     super(s);
     }
     
  public void run() {
    for(int i = 1; i <= 10; i++) {
     System.out.println("I am "+getName());
     try {
      sleep(1000); //暂停,每一秒输出一次
      }catch (InterruptedException e) {
      return;
     }
     }
   }
  }

注意:
1、线程睡眠是帮助所有线程获得运行机会的最好方法。
2、线程睡眠到期自动苏醒,并返回到可运行状态,不是运行状态。sleep()中指定的时间是线程不会运行的最短时间。因此,sleep()方法不能保证该线程睡眠到期后就开始执行。
3、sleep()是静态方法,只能控制当前正在运行的线程。

wait():
等待对象的同步锁,需要获得该对象的同步锁才可以调用这个方法,否则编译可以通过,但运行时会收到一个异常:IllegalMonitorStateException。
调用任意对象的 wait() 方法导致该线程阻塞,该线程不可继续执行,并且该对象上的锁被释放。
notify():
唤醒在等待该对象同步锁的线程(只唤醒一个,如果有多个在等待),注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
调用任意对象的notify()方法则导致因调用该对象的 wait()方法而阻塞的线程中随机选择的一个解除阻塞(但要等到获得锁后才真正可执行)。
notifyAll():
唤醒所有等待的线程,注意唤醒的是notify之前wait的线程,对于notify之后的wait线程是没有效果的。

sleep用于线程控制,而wait用于线程间的通信,与wait配套的方法还有notify和notifyAll.

区别一:
sleep是Thread类的方法,是线程用来 控制自身流程的,比如有一个要报时的线程,每一秒中打印出一个时间,那么我就需要在print方法前面加上一个sleep让自己每隔一秒执行一次。就像个闹钟一样。
wait是Object类的方法,用来线程间的通信,这个方法会使当前拥有该对象锁的进程等待知道其他线程调用notify方法时再醒来,不过你也可以给他指定一个时间,自动醒来。这个方法主要是用走不同线程之间的调度的。
区别二 :
关于锁的释放 ,在这里假设大家已经知道了锁的概念及其意义。调用sleep方法不会释放锁(自己的感觉是sleep方法本来就是和锁没有关系的,因为他是一个线程用于管理自己的方法,不涉及线程通信)
JDK 7 中的解释:
“public static void sleep(long millis)
throws InterruptedException
Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers.The thread does not lose ownership of any monitors.
 public final void wait() throws InterruptedException
Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. In other words,  this method behaves exactly as if it simply performs the call wait(0).The current thread must own this object's monitor. The thread releases ownership of this monitor and    waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method  the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.“  
调用wait方法会释放当前线程的锁(其实线程间的通信是靠对象来管理的,所有操作一个对象的线程是这个对象通过自己的wait方法来管理的,就好像这个对象是电视机,三个人是三个线程,那么电视机的遥控器就是这个锁,假如现在A拿着遥控器,电视机调用wait方法,那么A就交出自己的遥控器,由jVM虚拟机调度,遥控器该交给谁。)【我想到一个好玩的例子:如果A拿遥控器的期间,他可以用自己的sleep每隔十分钟调一次电视台,而在他调台休息的十分钟期间,遥控器还在他的手上~】
区别三:
使用区域  
由于wait函数的特殊意义,所以他是应该放在同步语句块中的,这样才有意义    。          

注意:两个方法都需要抛出异常

java多线程 sleep()和wait()的使用和区别_第1张图片

你可能感兴趣的:(java,多线程,并发)