Multithreading 14: Three major unsafe cases

Case 1: Buying tickets at the train station

Idea:

1. First, there must be a class BuyTicket for buying tickets. Multi-threads must implement the Runnable interface and rewrite run() to buy tickets.

2. To buy a ticket, you need to have a ticket. Define a ticket variable private int ticketNums = 10;

3. Write a ticket buying method buy(): first you have to determine whether there are tickets, if (ticketNums<=0), stop returning; 4. Otherwise, just buy tickets and just ticketNums--that's it. Who + got + which ticket 5. Then you need a loop, write it in the while method, define an external flag, and then call the method buy() to buy tickets. 6. Write the main method: first get a ticket, new to get the object station, and then three people (threads) operate the same object, new Thread(station,"Bitter Me").start, give a name Start the thread so you can get the tickets 7. Check the code: you can simulate a delay when judging whether there is a ticket to amplify the occurrence of the problem. Thread.sleep(100);

 1 package com.thread.syn;
 2 
 3 //Unsafe to buy tickets
 4 //Thread is not safe, there are negative numbers?
 5 //Because each thread interacts in its own working memory, improper memory control will cause data inconsistency. If 3 people grab the last ticket at the same time,
 6 //When three people bought it, they all saw 1, and they all copied 1 to their own memory. When the first person bought it, it became 0, and when the second person bought it, it became -1.
 7 public class UnsafeBuyTicket {
 8 
 9 public static void main(String[] args) {
10 BuyTicket station = new BuyTicket();
11
12 new Thread(station, “Bitter me”).start();
13 new Thread(station, “You guys are awesome”).start();
14 new Thread(station, “Abominable Scalper Party”).start();
15
16}
17}
18
19
20 class BuyTicket implements Runnable {
twenty one 
22 //tickets
23 private int ticketNums = 10;
24 boolean flag = true;//External stop mode
25
26 @Override
27 public void run() {
28
29 //Buy tickets
30 while (flag) {
31 try {
32 buy();
33 } catch (InterruptedException e) {
34 e.printStackTrace();
35}
36}
37 }
38
39 private void buy() throws InterruptedException {
40 //Determine whether there are tickets
41 if (ticketNums <= 0) {
42 flag = false;
43 return;
44}
45
46 //Analog delay
47 Thread.sleep(100);
48 //Buy tickets
49 System.out.println(Thread.currentThread().getName() + “get” + ticketNums–);
50 }
51
52 }
53
54 results:
55 You guys are awesome, you got 10
56 The hateful scalper got 8
57 I got 9 for my hard work
58 You guys are awesome, you got 7
59 I got 6 for my hard work
60 The hateful scalper gets 5
61 You guys are awesome, you got 4
62 I got 2 for my hard work
63 The hateful scalper got 3
64 You guys are awesome, you got 1
65 I got 0 for my hard work
66 The hateful scalper got -1

Case 2: Withdraw money from the bank

Idea:

1. First come to the Account class. The account must have a balance of money and a card number name. Let’s create a construction method Alt + Insert.

2. Bank: To simulate withdrawal Drawing, it is not safe to inherit a Thread class because it does not involve multiple threads operating the same object.

First, there is an account, then how much drawingMoney needs to be withdrawn, and how much nowMoney is in hand now. Write a construction method by yourself.

3. Rewrite the run() method and write the method of withdrawing money:

First determine whether there is money, the money in the account – if you want to get the money < 0, exit and return; Say a word and see who gets it + I don’t have enough money to get it. How to withdraw money specifically: First, the money in the account decreases; the balance in the card = balance - the money you withdraw account.money = account.money-drawingMoney; Money in hand: nowMoney =nowMoney + drawingMoney; Then print the account balance and the money in hand 4. Go to the main method and write: new An account, a wedding fund of 1 million, Then you withdraw money, open an account, withdraw 500,000, you Your girlfriend, also take the account, take 1 million, your girlfriend Then start two threads, and both you and your partner will withdraw money from the same account. 5. Write a delay Thread.sleep(100) to amplify the occurrence of the problem.

 1 package com.thread.syn;
 2 
 3 //Unsafe to withdraw money
 4 //Two people go to the bank to withdraw money. The account has 1 million. If you both see that it is 1 million, you can withdraw it.
 5 //But a negative number will appear after one operation, causing unsafe withdrawal of money.
 6 //The memory of the threads is separate and does not affect each other. They are all copied from the original place.
 7
 8 public class UnsafeBank {
 9 public static void main(String[] args) {
10 //Account
11 Account account = new Account(100, “Marriage Fund”);
12
13 Drawing you = new Drawing(account, 50, “you”);
14 Drawing girlFriend = new Drawing(account, 100, “girlFriend”);
15
16 you.start();
17 girlFriend.start();
18
19}
20}
twenty one 
twenty two 
23 //Account
24 class Account {
25 int money;//Balance
26 String name;//Card name
27
28 public Account(int money, String name) {
29 this.money = money;
30 this.name = name;
31}
32}
33
34 //Bank: simulate withdrawal
35 class Drawing extends Thread {
36
37 //Account
38 Account account;
39 //How much money was withdrawn
40 int drawingMoney;
41 //How much money do you have now?
42 int nowMoney;
43
44 public Drawing(Account account, int drawingMoney, String name) {
45 super(name);
46 this.account = account;
47 this.drawingMoney = drawingMoney;
48 }
49
50 //Withdraw money
51
52 @Override
53 public void run() {
54
55 //Judge whether there is money
56 if (account.money – drawingMoney < 0) {
57 System.out.println(Thread.currentThread().getName() + “Not enough money, can’t get it”);
58 return;
59 }
60
61 try {
62 Thread.sleep(100);
63 } catch (InterruptedException e) {
64 e.printStackTrace();
65 }
66
67 //Card balance = balance – you get money
68 account.money = account.money – drawingMoney;
69 //Money in your hand
70 nowMoney = nowMoney + drawingMoney;
71
72 System.out.println(account.name + “The balance is:” + account.money);
73 //Thread.currentThread().getName() = this.getName()
74 System.out.println(this.getName() + “Money in hand:” + nowMoney);
75
76 }
77 }
78
79 results:
80 The balance of the wedding fund is: 50
81 Money in your hand: 50
82 The balance of the wedding fund is: -50
83 girlFriend’s money: 100

Case 3: Thread-unsafe collection

 1 package com.thread.syn;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5
 6 //Thread-unsafe collection:
 7 //Because two threads operated the same position at the same moment and added two arrays to the same position, they overwrote it and there will be fewer elements.
 8 public class UnsafeList {
 9 
10 public static void main(String[] args) {
11
12 List<String> list = new ArrayList<>();
13 for (int i = 0; i < 10000; i + + ) {
14 new Thread(() -> {
15 list.add(Thread.currentThread().getName());
16 }).start();
17}
18 try {
19 Thread.sleep(3000);
20 } catch (InterruptedException e) {
21 e.printStackTrace();
twenty two         }
23 System.out.println(list.size());
twenty four     }
25}
26
27 results:
28 9993