文章目录
- [1. 背景](#1. 背景)
- [2. synchronized同步](#2. synchronized同步)
-
- [2.1 synchronized同步代码块](#2.1 synchronized同步代码块)
- [2.2 synchronized同步方法](#2.2 synchronized同步方法)
- [2.3 synchronized静态方法](#2.3 synchronized静态方法)
- [3. Lock](#3. Lock)
1. 背景
java
public class Demo2 {
public static void main(String[] args) {
// 创建子类对象
SellWindow2 sellWindow2 = new SellWindow2();
// 创建3个线程模拟窗口
Thread t1 = new Thread(sellWindow2);
Thread t2 = new Thread(sellWindow2);
Thread t3 = new Thread(sellWindow2);
t1.setName("A窗口");
t2.setName("B窗口");
t3.setName("C窗口");
t1.start();
t2.start();
t3.start();
//- 会有重复的票 - 会有不存在的票0 -1
}
}
class SellWindow2 implements Runnable{
int tickets = 100;
@Override
public void run() {
while (true) {
// 重复的原因
// 假设A抢到CPU执行权 此时tickets=100
// 如果B抢到了CPU的执行权 此时票为100 B也进来
// C也抢到 此时票是100
// 不存在的原因
// 假设A抢到CPU的执行权 此时tickets = 1
// B也抢到 此时 tickets = 1 也进来
// c执行 此时 tickets = 1 也进来
if (tickets > 0) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+
"卖了第" + tickets-- + "票");
// tickets--可以分为几步 1.取值 2.-1操作 3.赋予新值
// A 卖了第100
// B 卖了第100
// 最坏情况
// A窗口卖了第1张票 此时还剩0张
// B窗口卖了第0张票 此时还剩-1
// C窗口卖了第-1张票 此时还剩-2
}
}
}
}
2. synchronized同步
2.1 synchronized同步代码块
任意java对象 都可以充当对象 但是要保证是同一个
java
// 语法
sychronized(锁对象){
// 代码 对共享数据的操作
// 把非原子操作变成原子操作
}
// 谁能够充当锁对象
任意java对象 都可以充当对象 但是要保证是同一个
java
public class Demo1 {
public static void main(String[] args) {
SellWindow sellWindow = new SellWindow();
// 创建3个线程
Thread thread = new Thread(sellWindow);
Thread thread2 = new Thread(sellWindow);
Thread thread3 = new Thread(sellWindow);
thread.setName("A");
thread2.setName("B");
thread3.setName("c");
// STRART
thread.start();
thread2.start();
thread3.start();
}
}
class SellWindow implements Runnable{
int tickets = 100;
A obj = new A();
@Override
public void run() {
while (true) {
synchronized (obj) {
if (tickets > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+
"卖了第" + tickets-- +" 票");
}
}
}
}
}
class A{
}
2.2 synchronized同步方法
同步方法中的锁对象是
this
java
public class Demo2 {
public static void main(String[] args) {
SellWindow2 sellWindow = new SellWindow2();
// 创建3个线程
Thread thread = new Thread(sellWindow);
Thread thread2 = new Thread(sellWindow);
Thread thread3 = new Thread(sellWindow);
thread.setName("A");
thread2.setName("B");
thread3.setName("c");
// STRART
thread.start();
thread2.start();
thread3.start();
}
}
class SellWindow2 implements Runnable {
int tickets = 100;
//A obj = new A();
int i = 0;
@Override
public void run() {
while (true) {
if (i % 2 == 0) {
synchronized (this) {
if (tickets > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() +
"卖了第" + tickets-- + " 票");
}
}
} else {
sell();
}
i++;
}
}
private synchronized void sell() {
if (tickets > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() +
"卖了第" + tickets-- + " 票");
}
}
}
class A {
}
2.3 synchronized静态方法
静态方法中的锁对象是字节码文件对象 (.class对象)
java
public class Demo2 {
public static void main(String[] args) {
SellWindow2 sellWindow = new SellWindow2();
// 创建3个线程
Thread thread = new Thread(sellWindow);
Thread thread2 = new Thread(sellWindow);
Thread thread3 = new Thread(sellWindow);
thread.setName("A");
thread2.setName("B");
thread3.setName("c");
// STRART
thread.start();
thread2.start();
thread3.start();
}
}
class SellWindow2 implements Runnable {
static int tickets = 100;
Object obj = new Object();
int i = 0;
@Override
public void run() {
while (true) {
if (i % 2 == 0) {
// 对象.getClass
// 类名.class
synchronized (SellWindow2.class) {
if (tickets > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() +
"卖了第" + tickets-- + " 票");
}
}
} else {
sell();
}
i++;
}
}
private static synchronized void sell() {
if (tickets > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() +
"卖了第" + tickets-- + " 票");
}
}
}
class B {
}
3. Lock
Lock
实现提供了比使用 synchronized
方法和语句可获得的更广泛的锁定操作
java
- lock() 加锁
- unlock() 释放锁
java
public class Demo3 {
public static void main(String[] args) {
SellWindow3 sellWindow = new SellWindow3();
// 创建3个线程
Thread thread = new Thread(sellWindow);
Thread thread2 = new Thread(sellWindow);
Thread thread3 = new Thread(sellWindow);
thread.setName("A");
thread2.setName("B");
thread3.setName("c");
// STRART
thread.start();
thread2.start();
thread3.start();
}
}
class SellWindow3 implements Runnable{
int tickets = 100;
Lock lock = new ReentrantLock();
@Override
public void run() {
while (true) {
// 加锁
lock.lock();
try{
// 对共享资源的操作
if (tickets > 0) {
Thread.sleep(200);
System.out.println(Thread.currentThread().getName()
+"卖了第" + tickets-- + "票");
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 释放锁
lock.unlock();
}
}
}
}