synchronized 同步锁

Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。
一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
二、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
三、尤其关键的是,当一个线程访问object的其中一个synchronized(this)同步代码块时,其他线程对object中==所有其它==synchronized(this)同步代码块的访问将被阻塞。 只要锁相同的所有不同同步方法,其中一个方法被访问中,其他所有有相同锁的同步方法都被阻塞。
四、第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。
五、以上规则对其它对象锁同样适用.

synchronized 关键字,它包括两种用法:synchronized 方法和 synchronized 块。

synchronized 方法控制对类成员变量的访问:每个类实例对应一把锁,每个 synchronized 方法都必须获得调用该方法的类实例的锁方能执行,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法返回时才将锁释放,此后被阻塞的线程方能获得该锁,重新进入可执行状态。这种机制确保了同一时刻对于每一个类实例,其所有声明为 synchronized 的成员函数中至多只有一个处于可执行状态(因为至多只有一个能够获得该类实例对应的锁),从而有效避免了类成员变量的访问冲突(只要所有可能访问类成员变量的方法均被声明为 synchronized)。在 Java 中,不光是类实例,每一个类也对应一把锁,这样我们也可将类的静态成员函数声明为 synchronized ,以控制其对类的静态成员变量的访问。

测试示例

public class MainTest {

    public static void main(String[] args) {
        final MainTest test = new MainTest();
        new Thread(new Runnable() {

            @Override
            public void run() {
                MainTest.method();
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                test.methodDynamic();
            }
        }).start();
        new Thread(new Runnable() {
            // MainTest test = new MainTest();
            @Override
            public void run() {
                test.method();
            }
        }).start();
    }

    public static synchronized void method() {
        int i = 10;
        while (i-- > 0) {
            System.out.println(Thread.currentThread().getName()
                    + "  static method  " + i);
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {

            }
        }
    }

    public synchronized void methodDynamic() {
        int i = 10;
        while (i-- > 0) {
            System.out.println(Thread.currentThread().getName()
                    + "  static methodDynamic  " + i);
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {

            }
        }
    }
}

测试结果:

Thread-0  static method  9
Thread-1  static methodDynamic  9
Thread-1  static methodDynamic  8
Thread-0  static method  8
Thread-1  static methodDynamic  7
Thread-0  static method  7
Thread-0  static method  6
Thread-1  static methodDynamic  6
Thread-0  static method  5
Thread-1  static methodDynamic  5
Thread-1  static methodDynamic  4
Thread-0  static method  4
Thread-1  static methodDynamic  3
Thread-0  static method  3
Thread-0  static method  2
Thread-1  static methodDynamic  2
Thread-1  static methodDynamic  1
Thread-0  static method  1
Thread-0  static method  0
Thread-1  static methodDynamic  0
Thread-2  static method  9
Thread-2  static method  8
Thread-2  static method  7
Thread-2  static method  6
Thread-2  static method  5
Thread-2  static method  4
Thread-2  static method  3
Thread-2  static method  2
Thread-2  static method  1
Thread-2  static method  0

这样子就比较清楚了//

更详细资料可查阅这里写链接内容

同步锁,可类比文中房子 房间 钥匙 很形象

打个比方:一个object就像一个大房子,大门永远打开。房子里有 很多房间(也就是方法)。这些房间有上锁的(synchronized方法), 和不上锁之分(普通方法)。房门口放着一把钥匙(key),这把钥匙可以打开所有上锁的房间。另外我把所有想调用该对象方法的线程比喻成想进入这房子某个 房间的人。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值