一、概念
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 + "票");
//
// }
}