java--线程--锁-synchronize

来源:互联网 发布:mac版的au啥意思 编辑:程序博客网 时间:2024/05/21 17:05

参考

http://www.cnblogs.com/paddix/p/5374810.html

同步锁

原理

Java中每个对象都有一个内置锁。当程序运行到非静态的synchronized同步方法上时,自动获得与正在执行代码类的当前实例(this实例)有关的锁。获得一个对象的锁也称为获取锁、锁定对象、在对象上锁定或在对象上同步。当程序运行到synchronized同步方法或代码块时才该对象锁才起作用。一个对象只有一个锁。所以,如果一个线程获得该锁,就没有其他线程可以获得锁,直到第一个线程释放(或返回)锁。这也意味着任何其他线程都不能进入该对象上的synchronized方法或代码块,直到该锁被释放。释放锁是指持锁线程退出了synchronized同步方法或代码块。同步方法和同步代码块

同步

同步方法

同步代码块

代码块:如下,在多线程环境下,synchronized块中的方法获取了lock实例的monitor,如果实例相同,那么只有一个线程能执行该块内容

public class Thread1 implements Runnable {   Object lock;   public void run() {         synchronized(lock){         ..do something       }   }}

直接用于方法: 相当于上面代码中用lock来锁定的效果,实际获取的是Thread1类的monitor。更进一步,如果修饰的是static方法,则锁定该类所有实例

public class Thread1 implements Runnable {   public synchronized void run() {          ..do something   }}

重入锁

#

父类方法同步,子类重写该方法(没有synchronized关键字修饰),是没有同步作用的。线程占用锁的时候,如果执行的同步出现异常,会将锁让出。syncronized static 同步静态方法 锁对象为Class

改造

在判断/执行/输出的代码块加锁
    public void run() {        while (this.getX() > 30) {            synchronized (foo) {                if (this.getX() > 30) {                    this.fix(30);                    System.out.println(Thread.currentThread().getName() + " : 当前foo对象的x值= " + foo.getX());                }            }            try {                Thread.sleep(100);            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }

效果

Thread-B : 当前foo对象的x值= 70Thread-A : 当前foo对象的x值= 40Thread-A : 当前foo对象的x值= 10

分析

如果线程试图进入同步方法,而其锁已经被占用,则线程在该对象上被阻塞。同步损害并发性,应该尽可能缩小同步范围。同步不但可以同步整个方法,还可以同步方法中一部分代码块。线程睡眠时,它所持的任何锁都不会释放。
原创粉丝点击