多线程 synchronized对象锁和类锁------synchronized 中 this 和锁类.class

 

一、概念

synchronized 是 Java 中的关键字,是利用锁的机制来实现同步的。

锁机制有如下两种特性:

  • 互斥性:即在同一时间只允许一个线程持有某个对象锁,通过这种特性来实现多线程中的协调机制,这样在同一时间只有一个线程对需同步的代码块(复合操作)进行访问。互斥性我们也往往称为操作的原子性。

  • 可见性:必须确保在锁被释放之前,对共享变量所做的修改,对于随后获得该锁的另一个线程是可见的(即在获得锁时应获得最新共享变量的值),否则另一个线程可能是在本地缓存的某个副本上继续操作从而引起不一致。

二、对象锁和类锁

1. 对象锁

在 Java 中,每个对象都会有一个 monitor 对象,这个对象其实就是 Java 对象的锁,通常会被称为“内置锁”或“对象锁”。类的对象可以有多个,所以每个对象有其独立的对象锁,互不干扰。

2. 类锁

在 Java 中,针对每个类也有一个锁,可以称为“类锁”,类锁实际上是通过对象锁实现的,即类的 Class 对象锁。每个类只有一个 Class 对象,所以每个类只有一个类锁。

第一种

类锁

 


​​​​​​

package demo9;

public class Thread0201 {
	public static void main(String[] args) {
		BuyTicket Buy = new BuyTicket();
		BuyTicket Buy1 = new BuyTicket();
		BuyTicket Buy2 = new BuyTicket();
		Thread t1 = new Thread(Buy, "tom");
		Thread t2 = new Thread(Buy1, "黄牛");
		Thread t3 = new Thread(Buy2, "蔡依林");
		t1.start();
		t2.start();
		t3.start();

	}
}

class BuyTicket implements Runnable {
	private static int count = 20;
	private static int num = 0;
	private  boolean flag = true;

	@Override
	public void run() {
		while (flag) {
			//单个对象 的对象 用 this
//			synchronized(this) {
			//单个对象 多个对象  用 锁类
			synchronized(BuyTicket.class) {// ------------------采用 类锁------------------
				if (count < 1) {
					flag = false;
					return;
				}
				count--;
				num++;
				System.out.println(Thread.currentThread().getName() + "抢到了" + num + "票" + "还剩" + count + "票");
				
			}
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}		
		}
	}

//	private synchronized void cc() {
//
//		if (count < 1) {
//			flag = false;
//			return;
//		}
//		count--;
//		num++;
//		System.out.println(Thread.currentThread().getName() + "抢到了" + num + "票" + "还剩" + count + "票");
//
//	}
}

第二种

对象锁

 对于对象锁(this),如果是同一个实例,就会按顺序访问,但是如果是不同实例,就可以同时访问

package demo9;

public class Thread0201 {
	public static void main(String[] args) {
		//一份资源
		BuyTicket Buy = new BuyTicket();
//		BuyTicket Buy1 = new BuyTicket();
//		BuyTicket Buy2 = new BuyTicket();
		//多个代理
		Thread t1 = new Thread(Buy, "tom");
		Thread t2 = new Thread(Buy, "黄牛");
		Thread t3 = new Thread(Buy, "蔡依林");
		t1.start();
		t2.start();
		t3.start();

	}
}

class BuyTicket implements Runnable {
	private static int count = 20;
	private static int num = 0;
	private  boolean flag = true;

	@Override
	public void run() {
		while (flag) {
			//同步代码块 synchronized
			//单个对象 的对象 用 this
			synchronized(this) {	// ------------------采用 对象锁---------------			
			//单个对象 多个对象  用 类锁
//			synchronized(BuyTicket.class) {
				if (count < 1) {
					flag = false;
					return;
				}
				count--;
				num++;
				System.out.println(Thread.currentThread().getName() + "抢到了" + num + "票" + "还剩" + count + "票");
				
			}
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}		
		}
	}
	
//同步方法 synchronized

//	private synchronized void cc() {
//
//		if (count < 1) {
//			flag = false;
//			return;
//		}
//		count--;
//		num++;
//		System.out.println(Thread.currentThread().getName() + "抢到了" + num + "票" + "还剩" + count + "票");
//
//	}
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kjshuan

点个赞就好啦!!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值