JAVA线程sleep和wait方法区别

原文链接: http://www.cnblogs.com/diegodu/p/7866073.html

sleep 是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复,调用sleep 不会释放对象锁。由于没有释放对象锁,所以不能调用里面的同步方法。

sleep()使当前线程进入停滞状态(阻塞当前线程),让出CUP的使用、目的是不让当前线程独自霸占该进程所获的CPU资源,以留一定时间给其他线程执行的机会;
sleep()是Thread类的Static(静态)的方法;因此他不能改变对象的机锁,所以当在一个Synchronized块中调用Sleep()方法是,线程虽然休眠了,但是对象的机锁并木有被释放,其他线程无法访问这个对象(即使睡着也持有对象锁)。
在sleep()休眠时间期满后,该线程不一定会立即执行,这是因为其它线程可能正在运行而且没有被调度为放弃执行,除非此线程具有更高的优先级。

wait()方法是Object类里的方法;当一个线程执行到wait()方法时,它就进入到一个和该对象相关的等待池中,同时失去(释放)了对象的机锁(暂时失去机锁,wait(long timeout)超时时间到后还需要返还对象锁);可以调用里面的同步方法,其他线程可以访问;
wait()使用notify或者notifyAlll或者指定睡眠时间来唤醒当前等待池中的线程。
wiat()必须放在synchronized block中,否则会在program runtime时扔出”java.lang.IllegalMonitorStateException“异常。

sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常

sleep方法属于Thread类中方法,表示让一个线程进入睡眠状态,等待一定的时间之后,自动醒来进入到可运行状态,不会马上进入运行状态,因为线程调度机制恢复线程的运行也需要时间,一个线程对象调用了sleep方法之后,并不会释放他所持有的所有对象锁,所以也就不会影响其他进程对象的运行。但在sleep的过程中过程中有可能被其他对象调用它的interrupt(),产生InterruptedException异常,如果你的程序不捕获这个异常,线程就会异常终止,进入TERMINATED状态,如果你的程序捕获了这个异常,那么程序就会继续执行catch语句块(可能还有finally语句块)以及以后的代码。

注意sleep()方法是一个静态方法,也就是说他只对当前对象有效,通过t.sleep()让t对象进入sleep,这样的做法是错误的,它只会是使当前线程被sleep 而不是t线程

wait属于Object的成员方法,一旦一个对象调用了wait方法,必须要采用notify()和notifyAll()方法唤醒该进程;如果线程拥有某个或某些对象的同步锁,那么在调用了wait()后,这个线程就会释放它持有的所有同步资源,而不限于这个被调用了wait()方法的对象。wait()方法也同样会在wait的过程中有可能被其他对象调用interrupt()方法而产生

三 

这两者的施加者是有本质区别的. 
sleep()是让某个线程暂停运行一段时间,其控制范围是由当前线程决定,也就是说,在线程里面决定.好比如说,我要做的事情是 "点火->烧水->煮面",而当我点完火之后我不立即烧水,我要休息一段时间再烧.对于运行的主动权是由我的流程来控制.

支持一下吆 收藏一下: 很好    

而wait(),首先,这是由某个确定的对象来调用的,将这个对象理解成一个传话的人,当这个人在某个线程里面说"暂停!",也是 thisOBJ.wait(),这里的暂停是阻塞,还是"点火->烧水->煮饭",thisOBJ就好比一个监督我的人站在我旁边,本来该线 程应该执行1后执行2,再执行3,而在2处被那个对象喊暂停,那么我就会一直等在这里而不执行3,但正个流程并没有结束,我一直想去煮饭,但还没被允许, 直到那个对象在某个地方说"通知暂停的线程启动!",也就是thisOBJ.notify()的时候,那么我就可以煮饭了,这个被暂停的线程就会从暂停处 继续执行.


其实两者都可以让线程暂停一段时间,但是本质的区别是一个线程的运行状态控制,一个是线程之间的通讯的问题

 在java.lang.Thread类中,提供了sleep(),
而java.lang.Object类中提供了wait(), notify()和notifyAll()方法来操作线程
sleep()可以将一个线程睡眠,参数可以指定一个时间。
而wait()可以将一个线程挂起,直到超时或者该线程被唤醒。
    wait有两种形式wait()和wait(milliseconds).
sleep和wait的区别有:
  1,这两个方法来自不同的类分别是Thread和Object
  2,最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
  3,wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在
    任何地方使用
   synchronized(x){
      x.notify()
     //或者wait()
   }
   4,sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常

生产者与消费者模式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package  com.day19;
/**
  * 生产者与消费者线程
  * @author tenlee
  *
  */
public  class  ThreadDemo {
 
     public  static  void  main(String[] args) {
         Food food =  new  Food();
         Producter p =  new  Producter(food);
         Customer c =  new  Customer(food);
         Thread tp =  new  Thread(p);
         Thread tc =  new  Thread(c);
         tp.start();
         tc.start();
     }
}
//生产者
class  Producter  implements  Runnable {
     private  Food food;
     public  Producter(Food food) {
         this .food = food;
     }
     @Override
     public  void  run() {
         for ( int  i =  0 ; i <  50 ; i++) {
             if (i %  2  ==  0 ) { //偶数,生产xx菜
//              System.out.println("红烧肉----生产");
//              food.setName("红烧肉");
//              try {
//                  Thread.sleep(500);//做菜
//              } catch (InterruptedException e) {
//                  e.printStackTrace();
//              }
//              food.setEfficasy("好吃");
                 food.set( "红烧肉" "好吃" );
                 
             else  { //奇数,生产xx菜
//              System.out.println("脆皮鸡 生产");
//              food.setName("脆皮鸡");
//              try {
//                  Thread.sleep(500);//做菜
//              } catch (InterruptedException e) {
//                  e.printStackTrace();
//              }
//              food.setEfficasy("香脆");
                 food.set( "脆皮鸡" "香脆" );
             }
         }
     }
}
class  Customer  implements  Runnable {
     private  Food food;
     public  Customer(Food food) {
         this .food = food;
     }
     @Override
     public  void  run() {
         for ( int  i =  0 ; i <  50 ; i++){
//          try {
//              Thread.sleep(500);
//          } catch (InterruptedException e) {
//              // TODO Auto-generated catch block
//              e.printStackTrace();
//          }
//          System.out.println(food.getName() + "--->"
//                  + food.getEfficasy());
             food.get();
         }
     }
}
 
package  com.day19;
 
class  Food {
     private  String name; //菜名
     private  String efficasy; //功效
     private  boolean  flag =  true ;
     
     public  synchronized  void  set(String name, String efficasy) {
         if (!flag) { //1, 消费,不能生产
             try  {
                 this .wait(); //当前线程进入等待状态,并让出CPU,释放监视器的锁
             catch  (InterruptedException e) {
                 e.printStackTrace();
             }
         }
         System.out.println( "shengchan "  + name +  " "  + efficasy);
         this .setName(name);
         this .setEfficasy(efficasy);
         try  {
             Thread.sleep( 500 );
         catch  (InterruptedException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
         }
         flag =  false //开始消费
         this .notify();
     }
     public  synchronized  void  get() {
         if (flag) { //true是生产
             try  {
                 this .wait();
             catch  (InterruptedException e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
             }
         }
         System.out.println( this .getName() +  "xiaofei-->"  this .getEfficasy());
         try  {
             Thread.sleep( 500 );
         catch  (InterruptedException e) {
             e.printStackTrace();
         }
         flag =  true //开始生产
         this .notify();
     }
     public  Food() {
         
     }
 
     public  Food(String name, String efficasy) {
         super ();
         this .name = name;
         this .efficasy = efficasy;
     }
 
     public  String getName() {
         return  name;
     }
 
     public  void  setName(String name) {
         this .name = name;
     }
 
     public  String getEfficasy() {
         return  efficasy;
     }
 
     public  void  setEfficasy(String efficasy) {
         this .efficasy = efficasy;
     }
}

  

www.cnblogs.com/tenlee

转载于:https://www.cnblogs.com/diegodu/p/7866073.html

猜你喜欢

转载自blog.csdn.net/weixin_30302609/article/details/94792537