我们在使用多线程的时候,会遇到多个线程抢占同一资源问题,比如在厕所了里有三个坑位,小明内急进了第一个坑位上厕所,没关门没上锁,小红也有内急也来到了第一个坑位,推门而入,进去发现小明也在,那就尴尬了。
为了解决这种问题,于是有了我们的synchronized关键字同步代码块,废话不多说看代码。
public class Race implements Runnable {
/**
* 定义一个总坑位
*/
private int ticket = 10;
/**
* 抛出Thread.sleep的异常
*/
@SneakyThrows
@Override
public void run() {
while (true) {
if (ticket <= 0) {
break;
}
// 因为线程太快沉睡200ms
Thread.sleep(100);
// 打印第几张票
System.out.println(Thread.currentThread().getName() + "拿到了第" + ticket-- + "坑位");
}
}
public static void main(String[] args) {
// 创建对象
Race race = new Race();
// 放入对象,并给线程命名
new Thread(race, "李同学").start();
new Thread(race, "张同学").start();
new Thread(race, "老师").start();
}
}
以下是运行结果,其中张同学跟李同学都占了第七坑位,出现了我们上面遇到了尴尬情况,那怎么解决这种问题呢,就使用到了我们的synchronized关键字
我们使用synchronized关键字 先看代码
1. 第一种用同步代码块方式
public class Race implements Runnable {
/**
* 定义一个总坑位
*/
private int ticket = 10;
Object obj = new Object();
/**
* 抛出Thread.sleep的异常
*/
@SneakyThrows
@Override
public void run() {
while (true) {
synchronized (obj){
if (ticket <= 0) {
break;
}
// 因为线程太快沉睡200ms
Thread.sleep(100);
// 打印第几张票
System.out.println(Thread.currentThread().getName() + "拿到了第" + ticket-- + "坑位");
}
}
}
public static void main(String[] args) {
// 创建对象
Race race = new Race();
// 放入对象,并给线程命名
new Thread(race, "李同学").start();
new Thread(race, "张同学").start();
new Thread(race, "老师").start();
}
}
上面我们加入了synchronized关键字,括号内为任意对象锁,我们上面使用的是Object obj = new Object(); 的obj对象, 也可以使用 String str =""的str,任意对象锁都可以。看结果
加上我们的synchronized关键字 就不会出现两个同学去一个坑位的问题了。
1. 第二种用同步方法方式
public class Race implements Runnable {
/**
* 定义一个总坑位
*/
private int ticket = 10;
/**
* 抛出Thread.sleep的异常
*/
@SneakyThrows
@Override
public void run() {
while (true) {
if (this.method()) {
break;
}
}
}
public synchronized Boolean method() {
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + "拿到了第" + ticket-- + "票");
} else {
return ticket > 0;
}
return false;
}
public static void main(String[] args) {
// 创建对象
Race race = new Race();
// 放入对象,并给线程命名
new Thread(race, "李同学").start();
new Thread(race, "张同学").start();
new Thread(race, "老师").start();
}
}
以上