synchronized锁住的是什么
synchronized(Object.class)锁住的是Object.class对象,如下,若有某个方法如此加锁,那么该类的所有方法在此方法被某个线程使用时都被锁住。
public String[] split() { synchronized (Path.class) { ... } }
一般锁住Path.class是因为该类中提供了静态方法,为了保证静态方法的多线程共享时互斥,必须使用使用此种加锁方式锁住所有可能被多线程使用的方法。
synchronized(this) 等加锁代码块,加锁方法都是对对象上锁,某个线程调用了任一个上锁的地方,此对象的所有synchronized方法都被锁住,非synchronized方法没有被锁住。
如下代码可验证这一点:
public class SynObject{ public synchronized void method1(){ System.out.println("synchronized method1 is called"); try{ Thread.sleep(5000); }catch(Exception e){ } System.out.println("synchronized method1 is ending"); } public void method2(){ System.out.println("method2 is called"); } } public class ThreadTest{ public static void main(String[] args){ final SynObject sob = new SynObject(); Thread t1 = new Thread(new Runnable(){ public void run(){ System.out.println("Runnable is running..."); sob.method1(); try{ System.out.println("Runnable end"); }catch(Exception e){} } }); t1.start(); try{ Thread.sleep(1000); }catch(Exception e){ } sob.method2(); } }
method1方法执行需要5s钟,分线程在调用它,可以看此时主线程能不能调用method2.
method2没有加synchronized关键字时执行结果:
Runnable is running... synchronized method1 is called method2 is called synchronized method1 is ending Runnable end
加了synchronized关键字时执行结果:
Runnable is running... synchronized method1 is called synchronized method1 is ending Runnable end method2 is called
加锁是为了防止多线程同时访问同一个内存块,所以不难理解上述描述。