学习笔记
Java中的每个对象都可以作为锁。
-
普通同步方法,锁当前实例对象
//HashTable源码的put方法 public synchronized V put(K key, V value) { // Make sure the value is not null if (value == null) { throw new NullPointerException(); } // Makes sure the key is not already in the hashtable. Entry<?,?> tab[] = table; int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; @SuppressWarnings("unchecked") Entry<K,V> entry = (Entry<K,V>)tab[index]; for(; entry != null ; entry = entry.next) { if ((entry.hash == hash) && entry.key.equals(key)) { V old = entry.value; entry.value = value; return old; } } addEntry(hash, key, value, index); return null; }
-
静态同步方法,锁当前类的Class对象
//加锁类 public class SynchronizedSource { public static synchronized void method1(){ long start = System.currentTimeMillis(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("方法1启动时间:"+start); } public static synchronized void method2(){ long start = System.currentTimeMillis(); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("方法2启动时间:"+start); } public synchronized void method3(){ long start = System.currentTimeMillis(); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("方法3启动时间:"+start); } } //测试类 public class test { public static SynchronizedSource syntest=new SynchronizedSource(); public static void main(String[] args) { new Thread(new Runnable() { public void run() { syntest.method1(); } }).start(); new Thread(new Runnable() { public void run() { syntest.method2(); } }).start(); new Thread(new Runnable(){ public void run() { syntest.method3(); } }).start(); } } /*----------------------------------- 方法1启动时间:1610088821924 方法3启动时间:1610088821925 方法2启动时间:1610088822924 -----------------------------------*/
- 方法一和方法二对静态方法加锁,锁的是方法区中的Class对象,所以这两个方式抢占临界区,由于方法二抢占失败,只能等方法一执行结束,方法一执行过程中sleep了1000ms,sleep并不会释放锁,因此方法二的启动时间晚于方法一1000ms
- 方法三是对普通方法加锁,锁的是堆中实例对象,所以启动时间和方法1相差不大
-
同步代码块,锁的是括号中给出的对象
public class Singleton{ private Singleton(){} private Singleton instance; public Singleton getInstance(){ if(instance==null){ synchronized(Singleton.class){ if(instance==null) instance=new Singleton(); } } return instance; } }