A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Masumi 初级黑马   /  2019-9-12 15:32  /  1097 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

使用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对象,所以调用两个方法锁定的是同一个对象,即子类对象。
同步方法在执行时,如果出现异常,将会释放锁。


0 个回复

您需要登录后才可以回帖 登录 | 加入黑马