线程同步机制的实现
方式一:synchronized关键字来实现
public class AccountRunnableTest implements Runnable {
public int getBalance() {
return balance;
}
public void setBalance(int balance) {
this.balance = balance;
}
public AccountRunnableTest() {
}
public AccountRunnableTest(int balance) {
this.balance = balance;
}
private int balance;
private Demo d1 = new Demo();
@Override
public void run() {
synchronized (d1) { //需要一个引用(随意).必须是同一个
//模拟从后台查询余e
int tem = getBalance();
if(tem>= 200){
System.out.println("正在出钞,请稍后。。。。。。");
tem -=200;
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
System.out.println("余额不足,请重新输入");
}
setBalance(tem);
}
}
public static void main(String[] args) {
AccountRunnableTest art = new AccountRunnableTest(1000);
Thread t1 = new Thread(art);
Thread t2 = new Thread(art);
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("最终的账户余额为"+art.getBalance());
}
}
class Demo { }
方法二:使用Lock(锁)实现
import java.util.concurrent.locks.ReentrantLock;
public class AccountRunnableTest implements Runnable {
public int getBalance() {
return balance;
}
public void setBalance(int balance) {
this.balance = balance;
}
public AccountRunnableTest() {
}
public AccountRunnableTest(int balance) {
this.balance = balance;
}
private int balance;
private ReentrantLock lock = new ReentrantLock();//准备了一把锁
@Override
public void run() {
//开始加锁
lock.lock();
//模拟从后台查询余e
int tem = getBalance();
if(tem>= 200){
System.out.println("正在出钞,请稍后。。。。。。");
tem -=200;
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
System.out.println("余额不足,请重新输入");
}
setBalance(tem);
lock.unlock();//解锁
}
public static void main(String[] args) {
AccountRunnableTest art = new AccountRunnableTest(1000);
Thread t1 = new Thread(art);
Thread t2 = new Thread(art);
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("最终的账户余额为"+art.getBalance());
}
}
生产者消费者模型
/**
* 编程实现仓库类
*/
public class StoreHouse {
private int cnt = 0; // 用于记录产品的数量
public synchronized void produceProduct() {
notify();
if (cnt < 10) {
System.out.println("线程" + Thread.currentThread().getName() + "正在生产第" + (cnt+1) + "个产品...");
cnt++;
} else {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void consumerProduct() {
notify();
if (cnt > 0) {
System.out.println("线程" + Thread.currentThread().getName() + "消费第" + cnt + "个产品");
cnt--;
} else {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
----------------------------------------------------------------------
public class StoreHouseTest {
public static void main(String[] args) {
// 创建仓库类的对象
StoreHouse storeHouse = new StoreHouse();
// 创建线程类对象并启动
ProduceThread t1 = new ProduceThread(storeHouse);
ConsumerThread t2 = new ConsumerThread(storeHouse);
t1.start();
t2.start();
}
}
/**
* 编程实现生产者线程,不断地生产产品
*/
public class ProduceThread extends Thread {
// 声明一个仓库类型的引用作为成员变量,是为了能调用调用仓库类中的生产方法 合成复用原则
private StoreHouse storeHouse;
// 为了确保两个线程共用同一个仓库
public ProduceThread(StoreHouse storeHouse) {
this.storeHouse = storeHouse;
}
@Override
public void run() {
while (true) {
storeHouse.produceProduct();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class ConsumerThread extends Thread {
// 声明一个仓库类型的引用作为成员变量,是为了能调用调用仓库类中的生产方法 合成复用原则
private StoreHouse storeHouse;
// 为了确保两个线程共用同一个仓库
public ConsumerThread(StoreHouse storeHouse) {
this.storeHouse = storeHouse;
}
@Override
public void run() {
while (true) {
storeHouse.consumerProduct();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
![](https://img-blog.csdnimg.cn/48edb81644f647c3885b9f0f3bdb1e98.png)