标签:
一、举几个栗子??
1.当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
2.当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
3.当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其他sychronized(this)同步代码块的访问将阻塞。
4.第三个例子也可以用synchronized方法来实现。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。(方法m4t2xx的synchronized关键字可以在public后,也可以在public前)
二、概述
synchronized是针对一个临界区的,所谓临界区就是指访问这个地方最多只能有一个线程在里面(就像一支笔可以被多个人用,但是同一时刻只能有一个人用)。synchronized能做到这一点,它通过在对象上加锁后进入临界区来达到临界区串行访问的目的,而对象本身的作用域将决定锁的粒度。
普通方法前加synchronized:
synchronized public void test() {...}
该操作等价于在方法体前后包装了一个synchronized(this),或者说给当前类所在对象加上了锁对象。
静态方法前加synchronized:
synchronized public static void test() {...}
这个锁操作等价于锁住了当前类的class对象,比如这个类叫作A,那么相当于执行了synchronized(A.class)操作。
synchronized主要就是这两种方式,其余的操作方式都是在这个基础上衍生出来的。例如“代码块加锁”:
锁住的其实并不是代码块,而是object这个对象,因此在其他代码中也发生synchronized(object)时就会发生互斥。
其实synchronized(this)也是用这样的方式衍生出来的,只是在方法前面增加synchronized与之有一个区别,就是它的粒度并不是在方法级别,而是在某个指定的代码块级别。
在临界区内多个线程的操作绝对是串行的,这一点Java是肯定可以保证的。
但是,synchronized造成的开销也是很大的。
标签: