本小白死而复生,又回来了。
今天讲一下线程基础。使用多线程实现生产者与消费者模式来模拟一个存取钱的过程。愿各位大神,大佬多多指教。
我们一般同步用synchronized,如果你想要用高级一点的,用lock,但别忘了释放一下,不理会发生死锁的哦,同学。
另外,* sleep 与 wait的区别?
- sleep:让线程进入休眠状态,让出CPU的时间片,不释放对象监视器的所有权。
- wait:让线程进入休眠状态,让出CPU的时间片,并释放对象监视器的所有权,等待其他线程通过notify方法来唤醒。
直接上代码。
package com.vince;
public class ProducterCustomerDemo02 {
public static void main(String[] args) {
Account account = new Account(10000);
Saver s = new Saver(account);
Comsumper c = new Comsumper(account);
Thread t1 = new Thread(s);
Thread t2 = new Thread(c);
t1.start();
t2.start();
}
}
class Saver implements Runnable{
private Account account;
public Saver(Account account) {
this.account = account;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
if (i%2==0){
account.set(1000,"存入");
}else {
account.set(500,"存入");
}
}
}
}
class Comsumper implements Runnable{
private Account account;
public Comsumper(Account account) {
this.account = account;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
account.get(1000,"取出");
}
}
}
/*
* 账户
* */
class Account{
private int cash = 10000;
private String operation;
private boolean flag = true; //true表示可以生产,false表示可以消费
/*
* 消费
* */
public synchronized void get(int consumption,String consume ){
//不能消费的情况
if (flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.cash = this.getCash() - consumption;
this.setOperation(consume+consumption+"元");
System.out.println(this.getOperation()+",余额为"+this.cash);
flag = true;
this.notify();
}
/*
* 生产
* */
public synchronized void set(int storage,String save ){
//不能生产的情况
if (!flag){
try {
this.wait(); //线程进入等待状态,释放监听器的所有权(对象锁)
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.cash = this.getCash() + storage;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.setOperation(save+storage+"元");
System.out.println(this.getOperation()+",余额为"+this.cash);
flag = false;
this.notify();
}
public Account(int cash) {
this.cash = cash;
}
public Account(int cash, String operation) {
this.cash = cash;
this.operation = operation;
}
public int getCash() {
return cash;
}
public void setCash(int cash) {
this.cash = cash;
}
public String getOperation() {
return operation;
}
public void setOperation(String operation) {
this.operation = operation;
}
@Override
public String toString() {
return "Account{" +
"cash=" + cash +
", operation='" + operation + '\'' +
'}';
}
}
可能出现的结果:
C:\Java\jdk1.8.0_181\bin\java.exe ...
存入1000元,余额为11000
取出1000元,余额为10000
存入500元,余额为10500
取出1000元,余额为9500
存入1000元,余额为10500
取出1000元,余额为9500
存入500元,余额为10000
取出1000元,余额为9000
存入1000元,余额为10000
取出1000元,余额为9000
存入500元,余额为9500
取出1000元,余额为8500
存入1000元,余额为9500
取出1000元,余额为8500
存入500元,余额为9000
取出1000元,余额为8000
存入1000元,余额为9000
取出1000元,余额为8000
存入500元,余额为8500
取出1000元,余额为7500
存入1000元,余额为8500
取出1000元,余额为7500
存入500元,余额为8000
取出1000元,余额为7000
存入1000元,余额为8000
取出1000元,余额为7000
存入500元,余额为7500
取出1000元,余额为6500
存入1000元,余额为7500
取出1000元,余额为6500
存入500元,余额为7000
取出1000元,余额为6000
存入1000元,余额为7000
取出1000元,余额为6000
存入500元,余额为6500
取出1000元,余额为5500
存入1000元,余额为6500
取出1000元,余额为5500
存入500元,余额为6000
取出1000元,余额为5000
Process finished with exit code 0
注:这个是在IDEA上跑的,Eclipse可能会稍有出入。