多线程的一个经典问题: 当商品只有一个时,当有人来买东西时,老板又将它同时售卖个另一个人,导致重复售卖同一件物品:又或是有100件商品,但有200人同时购买,该如何分配?
在Java中就有当多个线程共享一个数据时,如果处理不当,容易出现线程的安全问题。
Java中就出现了synchronized
关键词来声明同步方法
当一个对象被synchronized
修饰,任何时候只有一个线程能访问该对象
当一个方法被synchronized
修饰,当一个线程要执行该方法时,其他线程要执行该方法则要等待该线程执行完该方法。
模型如下:
public class Main {
public static void main(String[] args) {
Warehouse warehouse = new Warehouse(100);
Producer p1 = new Producer("01",warehouse);
Producer p2 = new Producer("02",warehouse);
Customer c1 = new Customer("01",warehouse);
Customer c2 = new Customer("01",warehouse);
p1.start();
p2.start();
c1.start();
c2.start();
}
}
public class Customer extends Thread{
private Warehouse warehouse;
private String name;
public Customer() {}
public Customer(String name,Warehouse warehouse) {
this.name = name;
this.warehouse = warehouse;
}
public void run(){
try {
warehouse.removeCount(name);
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Producer extends Thread{
private Warehouse warehouse;
private String name;
public Producer() {}
public Producer(String name,Warehouse warehouse) {
this.name = name;
this.warehouse = warehouse;
}
public void run(){
try {
warehouse.addCount(name);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Warehouse {
private int count = 0;
private int size;
public Warehouse() {}
public Warehouse(int size) {
this.size = size;
}
public synchronized void addCount(String name) {
while (count == size){
try {
this.wait();//等待并释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
count++;
System.out.println(name + "正在生产一件商品,库存:" + count);
this.notify();//唤醒其他线程
}
public synchronized void removeCount(String name) {
while (count == 0){
try {
this.wait();//等待并释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
count--;
System.out.println(name + "正在销售一件商品,库存:" + count);
this.notify();//唤醒其他线程
}
}
ut.println(name + "正在销售一件商品,库存:" + count);
this.notify();//唤醒其他线程
}
}