/**
* 4.10多线程--习题一(购票)
* 1. 创建新线程的内部代码需要考虑线程安全问题
* 2. int amount = window.sell(randomAmount()); 与 amountList.add(amount); 是两个不同的对象,他们的组合不存在安全问题
* 3. 通过 Thread.sleep(500); 来模拟现实中可能发生的上下文切换,如果没有这段代码,因为逻辑代码太少,很可能不发生上下文切换,也就没法看到想要的效果
* 4. Vector Random 是线程安全的
* 5. amountList.stream().mapToInt(i->i).sum())
*/
public class Demo1 {
public static void main(String[] args) {
//模拟多人买票
TicketWindow window = new TicketWindow(20000);
// 2000 人同时买票
List<Thread> threadList = new ArrayList<>();//全部线程
List<Integer> amountList = new Vector<>();//卖出票数
for (int i = 0; i < 2000; i++) {
Thread thread = new Thread(()->{
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
int amount = window.sell(randomAmount());//需要考虑线程安全问题
amountList.add(amount);//需要考虑线程安全问题
});
threadList.add(thread);
thread.start();
}
for (Thread thread : threadList) {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//所有线程结束后,检验是否正确
System.out.println("余票数量:"+window.getCount());
System.out.println("卖出的票数:"+amountList.stream().mapToInt(i->i).sum());
System.out.println("总票数:"+(window.getCount() + amountList.stream().mapToInt(i->i).sum()));
}
// Random 是线程安全的
static Random random = new Random();
//随机 1-5
public static int randomAmount(){
return random.nextInt(5)+1;
}
}
//售票窗口
class TicketWindow{
private int count;//余票数量
public TicketWindow(int count) {
this.count = count;
}
public int getCount() {
return count;
}
//售票,购买数量
public synchronized int sell(int amount){
if(this.count >= amount){
this.count -= amount;
return amount;
} else {
return 0;
}
}
}
/**
* 4.10多线程--习题二(转账)
* 1.synchronized (Account.class) 不推荐使用
*/
public class Demo2 {
public static void main(String[] args) throws InterruptedException {
Account a = new Account(1000);
Account b = new Account(1000);
Thread t1 = new Thread(()->{
for (int i = 0; i < 500; i++) {
a.transfer(b,randomAmount());
}
},"t1");
Thread t2 = new Thread(()->{
for (int i = 0; i < 500; i++) {
b.transfer(a,randomAmount());
}
},"t2");
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(a.getMoney());
System.out.println(b.getMoney());
System.out.println(a.getMoney() + b.getMoney());
}
// Random 是线程安全的
static Random random = new Random();
//随机 1-100
public static int randomAmount(){
return random.nextInt(100)+1;
}
}
//账号
class Account{
private int money;//余额
public Account(int money) {
this.money = money;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
//转账
public void transfer(Account target, int amount){
synchronized (Account.class){
if(this.money >= amount){
this.setMoney(this.money - amount);
target.setMoney(target.getMoney() + amount);
}
}
}
}