黑马程序员技术交流社区

标题: Synchronize关键字 [打印本页]

作者: Masumi    时间: 2019-9-12 15:32
标题: Synchronize关键字
使用Synchronized关键字给一个对象加锁第一种方式:synchronize代码块,锁定自己创建的对象
[Java] 纯文本查看 复制代码
                public class T {
                    private int count = 10;
                    private Object o = new Object();
               
                    public void m() {
                        synchronized (o) {
                            //任何线程要执行sychronized中的代码,必须先拿到对象o的锁
                            //只要一个线程调用了m方法,在执行到synchronized代码块时
                            //必须先拿到o的锁,
                            count--;
                            System.out.println(Thread.currentThread().getName() + "count=" + count);
                        }
                    }


第二种方式:synchrinize代码块锁定this对象
[Java] 纯文本查看 复制代码
                public class T {
                    private int count = 10;
               
                    public void m() {
                        //第二种写法,不用new一个Object,直接用该对象自身作为锁
                        synchronized (this) {
                            count--;
                            System.out.println(Thread.currentThread().getName() + "count=" + count);
                        }
                    }


第三种方式:synchronize锁定方法,锁定的也是this对象
[Java] 纯文本查看 复制代码
                public class T {
                    private int count = 10;
               
                    public synchronized void m() {
                        //相当于sychronized(this){}
                        //注意sychronized锁定的不是代码块中的代码,而是this对象
                        count--;
                        System.out.println(Thread.currentThread().getName() + "count" + count);
                    }
                }


使用synchronize锁定静态方法时,相当于锁定当前类的class对象(o.class)
[Java] 纯文本查看 复制代码
                public class T {
                    private static int count = 10;
               
                    private synchronized static void m() {
                        //锁定静态方法
                        count--;
                        System.out.println(Thread.currentThread().getName() + "count" + count);
                    }
               
                    //相当于锁定当前类的class对象
                    private static void m2() {
                        synchronized (T.class) {
                            count--;
                            System.out.println(Thread.currentThread().getName() + "count" + count);
                        }
                    }
                }



一个synchronized代码块中的代码相当于一次原子操作,要么都不执行,要么全部执行,不会被其它线程打断
在同一个对象的非同步方法和同步方法可以同时执行
脏读
1.对写数据的方法加锁,但对读数据的方法不加锁
写数据的方法中,除了写数据,可能还有其它的业务代码。如果写的过程中执行读数据的方法,可能读出还未进行写入的数据。
2.是否允许脏读要看具体情况
synchronized获得的锁是可重入的。
一个线程已经拥有某个对象的锁,再次申请时仍会获得该对象的锁。
一个线程获得了子类对象的锁,可以调用父类的同步方法。因为synchronized锁定的是this对象,所以调用两个方法锁定的是同一个对象,即子类对象。
同步方法在执行时,如果出现异常,将会释放锁。







欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2