关闭

2 线程的基础知识(中)

81人阅读 评论(0) 收藏 举报
分类:

Continued Chapter,Sleep()和Wait()的相同与区别?

相同:1从使用结果:都会让程序从从运行状态(Running)到阻塞状态(Blocked)。

区别:1Sleep()属于Thread类下的方法,

static void sleep(long millis)
          在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。
Wait()属于Object类方法

Continued Chapter

 void wait()
          在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。
 void wait(long timeout)
          在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量前,导致当前线程等待。
 void wait(long timeout, int nanos)
          在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。
2 关于面试中经常问到这两个有关锁的问题

首先锁是什么?为什么要这个锁?锁(Lock):你可以把它想象成一个权限,只有当你拿到这个权限的时候你才能用。好了这个权限是什么呢?应为在线程当作,我们往往会编写大量的线程,这些线程不可能每个都重新开资源,把相同的资源拿出来,我们来同步代码块,这些代码块之类的就是锁了。

拿个别人的列子:

我要输出1到10000,建立10个线程来输出。
public class ThreadTest1 extends Thread {   
    private int threadNo;   
    public ThreadTest(int threadNo) {   
        this.threadNo = threadNo;   
    }   
    public static void main(String[] args) throws Exception {   
        for (int i = 1; i < 10; i++) {   
           new ThreadTest(i).start();   
            Thread.sleep(1);   
        }   
     }   
    
    @Override  
     public void run() {   
        for (int i = 1; i < 1000; i++) {   
            System.out.println("No." + threadNo + ":" + i);   
        }   
     }   
 }  
这个只是简单的重写run()方法,再来看看带Synchonized()和Lock()
public class ThreadTest extends Thread {   
    private int threadNo;   
    public ThreadTest(int threadNo) {   
        this.threadNo = threadNo;   
    }   
    public static void main(String[] args) throws Exception {   
        for (int i = 1; i < 10; i++) {   
           new ThreadTest(i).start();   
            Thread.sleep(1);   
        }   
     }   
    
    @Override  
     public synchronized void run() {   
        for (int i = 1; i < 10000; i++) {   
            System.out.println("No." + threadNo + ":" + i);   
        }   
     }   
 }  
这个使用了synchronized()同步方法的,Java中用同步监视器来解决进程并发造成的异常,我们上面用的是同步方法(讲下怎么使用呢就是用synchronized关键字来修饰方法,这样就称为同步方法)。虽然这样我们已经觉得很方便了,但是人的创造是无穷的,后来人们有在此基础上,提出了锁的概念,这个具有更强大的功能。

import java.util.concurrent.locks.ReentrantLock;

public class ThreadTest2 extends Thread {   
	 private int threadNo; 
	 private ReentrantLock lock=new ReentrantLock();
	 public ThreadTest2(int threadNo) {   
	  this.threadNo = threadNo;   
	     }   
	public static void main(String[] args) throws Exception {   
	    
	     for (int i = 1; i < 10; i++) {     
	  new ThreadTest2(i).start();   
	      Thread.sleep(1);   
	     }   
	  }     
	public void run() {     
	 lock.lock();
	 
	 try{   
	      for (int i = 1; i < 1000; i++) {   
	       System.out.println("No." + threadNo + ":" + i);   
	    }      
	 }  
	 finally
	 {
		 lock.unlock();
	 }
	 }   
	 }
这3个代码效果是一样的,但是我们发现这不是我们想要的。以为经过对比,我们发现无论有没有加synchronized()同步方法,还是直接上锁,我们都对的是run()方法,换个说法,线程自身作为对象锁,这显然没用。

如果我们要对线程进行同步,就要对同步对象进行上锁,这些对象需要共享且是唯一的,如何进行上锁呢?

public class ThreadTest extends Thread {   
    private int threadNo;   
    private  String men;
    public ThreadTest(int threadNo,String men) {   
        this.threadNo = threadNo;   
        this.men=men;
    }   
    public static void main(String[] args) throws Exception {   
    String men=new String();
        for (int i = 1; i < 10; i++) {   
           new ThreadTest(i,men).start();   
            Thread.sleep(1);   
        }   
     }   
    
    @Override  
     public void run() { 
    	synchronized(men){
        for (int i = 1; i < 1000; i++) {   
            System.out.println("No." + threadNo + ":" + i);   
        }  
    	}
     }   
 }  
这个就可以实现每个线程单独打印出1到1000个数。

讲了这么多,那Sleep()和Wait()在对待锁到底有什么区别呢?

Sleep()执行的时候是不会释放锁的,该监控对象依然存在,只是时间到了才会释放。

而Wait()会放弃对象锁,进入等待此对象的等待池。除非被noifty()或者noiftyAll()唤醒。



Continued Chapter
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:20017次
    • 积分:1435
    • 等级:
    • 排名:千里之外
    • 原创:128篇
    • 转载:1篇
    • 译文:0篇
    • 评论:0条