sleep是让线程暂停指定的时间,wait是让线程等待,知道有notify方法出现在继续运行,sleep不释放对象锁,wait释放对象锁。这在很多地方都有写到,但没有例子不好理解
- import java.util.ArrayList;
- import java.util.List;
- public class thread {
- public List list=new ArrayList();
- Integer i=0;//新建一个对象,随便什么,就为了借用它的锁而已。
- public static void main(String[] args){
- thread th=new thread();
- A a=th.new A();
- B b=th.new B();
- Thread add=new Thread(a);
- Thread get=new Thread(b);
- add.start();
- get.start();
- }
- class A extends Thread{
- public void run(){
- synchronized(i){
- try {
- //Thread.sleep(1000);
- i.wait();//这里调用了对象i的wait方法,那么就表示所在线程暂时放弃i的对象锁,并阻塞在这里,同时把机会让给同样使用i锁的B线程执行
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- for(int j=0;j<list.size();j++){
- System.out.print(list.get(j));
- }
- }
- }
- }
- class B extends Thread{
- public void run(){
- synchronized(i){
- for(int j=0;j<10;j++){
- list.add(j);
- }
- i.notify();//这里调用了i的notify方法,表示B线程用完i锁了,现在可以归还了,此时A线程就会在得到锁,并继续执行。
- }
- }
- }
- }
从如上代码中可见,线程B是负责向集合中加值的,线程A是负责从集合中取值的,如果不进行同步处理,那么如果两个线程同时运行,那么A可能在B加入值之前就从集合中取值,那么就会报错,所以必须进行同步代码的操作(也可以加入flag来判断是否到了A中从集合里取值的时机)。
而用sleep就没有上面的功能了,因为从代码中可以发现,不管是A线程先抢到cpu开始执行还是B线程先执行,他们中的一个肯定会拿到i的锁的,但拿到后i的锁就没有使用wait方法释放过,那假设B先拿到锁了,向list中加入值完成了,那也别指望A能打印出来,因为A一直阻塞在(i){
这个位置,一直在等待i的对象锁。没有锁就不会向下执行。
synchronized