每一个java对象都有一个内部对象锁(又称作隐式监视器锁),
我们在理解上,为了方便理解,可以简单的等同于,一个对象包含一个隐式监视器+一个隐式锁。

锁有以下几个作用
1.锁用来保护代码片段,任何时刻只能有一个线程执行被保护的代码。
2.锁可以管理试图进入被保护代码段的线程。
3.锁可以拥有一个或多个相关的条件对象。
4.每个条件对象管理那些已经进入被保护的代码段但还不能运行的线程。



每个隐式监视器又包含一些特定的监视器方法。我们查看jdk api 最基础的Object对象可以得知
wait() 
 notify() 方法或 notifyAll() 方法前,导致当前线程等待。
notify() 
          唤醒在此对象监视器上等待的单个线程。
notifyAll() 
          唤醒在此对象监视器上等待的所有线程。



使用synchronized 方法或语句的使用提供了对与每个对象相关的隐式监视器锁的访问。在使用这个语义的时候,我们无需关心加锁和锁的释放,一切都是隐式的自动化完成。



这个例子非常经典的描述锁的使用,可以把同步标示去除看看执行的顺序。

public class Test extends Thread {   
       private int threadNo;
       private String lock; 
  
       public ThreadTest2(int threadNo, String lock) {  
            this.threadNo = threadNo;   
            this.lock = lock;  
       }   
       
      public static void main(String[] args) throws Exception {   
            String lock = new String("lock");   
            for (int i = 1; i < 100; i++) {     
                  new Test(i, lock).start();   
            }   
      }      
 
    public void run() {     
          synchronized (lock) {   
             for (int i = 1; i < 3; i++) {   
                 System.out.println("No." + threadNo + ":" + i);   
             }      
          }     
    }   
}