2、synchronized

synchronized   锁的是对象不是代码
对某个对象加锁

public class T{
	private int count = 10;
	private Object o = new Object();

	public void m(){
		synchronized(o){   	//任何线程要执行下面的代码,必须先拿到o的锁
			count--;
			system.out.println(Thread.cunrentThread().getName() + "count = " + count);
		}
	}
}

对象头64位 有两位实现锁

public class T{
    private int count = 10;
    public void m(){
        synchronized(this){       //任何线程要执行下面的代码,必须先拿到this的锁
            count--;
            system.out.println(Thread.cunrentThread().getName() + "count = " + count);
        }
    }
}
public class T{
	private int count = 10;
//任何线程要执行下面的代码,必须先拿到锁
	public synchronized void  m(){   	
			count--;
			system.out.println(Thread.cunrentThread().getName() + "count = " + count);
		}
}

static类型

public class T{
	private static int count = 10;
	public synchronized static void  m(){   	 //这里等同于synchronized (T.class)
			count--;
			system.out.println(Thread.cunrentThread().getName() + "count = " + count);
		}
	public static void  m(){   
		synchronized (T.class)	
			count--;
		}
}

synchronized既保证了原子性又保证了可见性 

public class T implements Runnable{
	private int count = 10;
	public /*synchronized*/ void run(){
		count --;
		System.out.println(count);
	}

	public static void main(String[] args){
		T t = new T();
		for(int i = 0; i<100; i++){
			new Thread( t, "THREAD" + i ).start();
		}

	}
}

同步方法和非同步方法是否可以同时调用   可以

public  class  T{
	public synchronized void m1(){
		System.out.println("m1 start...");
		try{
			Thread.sleep(10000);
		} catch(InterruptedException e) {
		 	e.printStackTrace();
		}
		System.out.println("m1 end");
	}

	public void m2(){
		try{
			Thread.sleep(5000);
		} catch(InterruptedException e) {
		 	e.printStackTrace();
		}
		System.out.println("m2");
	}

	public static void main(String[] args){
		T t = new T();
		/*new Thread(()->t.m1(),"t1").start();
		new Thread(()->t.m2(),"t2").start();*/
		new Thread(t::m1,"t1").start();
		new Thread(t::m2,"t2").start();
	}
}
m1 start...
m2
m1 end

模拟银行账户  对业务写方法加锁 对业务读方法不加锁 

public class Account {
	String name;
	double balance;

	public synchronized void set(String name, double balance) {
		this.name = name;

		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		this.balance = balance;
	}

	public /* synchronized */ double getBalance(String name) {
		return this.balance;
	}

	public static void main(String[] args) {
		Account a = new Account();
		new Thread(() -> a.set("zhangsan", 100.0)).start();

		try {
			TimeUnit.SECONDS.sleep(1);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(a.getBalance("zhangsan"));

		try {
			TimeUnit.SECONDS.sleep(2);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(a.getBalance("zhangsan"));
	}
}

==
synchronized 可重入锁   必须指同一个线程里面
如果程序中出现异常 锁会被释放
==
synchronized 的底层实现:
JDK早期的时候       重量级      - OS
后来的改进
锁升级的概念:
    我就是厕所所长(一、二)
sync(Object)
markWord  记录这个线程ID  (偏向锁)
如果有线程争用:升级为 自旋锁   用户态  执行时间短(加锁代码)线程数少
10次之后   
升级为  重量级锁  - OS  申请资源加锁  内核态    执行时间长、线程数多  等待队列
==
synchronized(Object)
   “Object”不能用String常量 Integer Long
==
final Object o = new Object();
synchronized(o)
==

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值