Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

JAVA multithreaded programming instance


May 30, 2021 Article blog



1. Three ticket windows sell 20 tickets at the same time

Program Analysis: (1) To use the same static value (2) to ensure that the same vote is not sold, java multithreaded synchronization lock. D esign ideas: (1) Create a platform class Stage, inherit Thread, rewrite the run method, and perform ticketing operations in the run method! T icket sales to use synchronization lock: that is, there is a platform to sell this ticket, other platforms to wait for this ticket to sell out! (2) Create a main method call class

(i) Create a platform class to inherit Thread

package com.xykj.threadStation;
public class Station extends Thread {
   // 通过构造方法给线程名字赋值
   public Station(String name) {
      super(name);// 给线程名字赋值
  }
   // 为了保持票数的一致,票数要静态
   static int tick = 20;    
   // 创建一个静态钥匙
   static Object ob = "aa";//值是任意的
   // 重写run方法,实现买票操作
   @Override
   public void run() {
     while (tick > 0) {
         synchronized (ob) {// 这个很重要,必须使用一个锁,
         // 进去的人会把钥匙拿在手上,出来后才把钥匙拿让出来
         if (tick > 0) {
           System.out.println(getName() + "卖出了第" + tick + "张票");
           tick--;
        } else {
           System.out.println("票卖完了");
        }
      }
       try {
           sleep(1000);//休息一秒
      } catch (InterruptedException e) {
         e.printStackTrace();
      }
    }
}
}

(ii) Create a master method call class

package com.xykj.threadStation;
public class MainClass {
 /**
 * java多线程同步锁的使用
  * 示例:三个售票窗口同时出售10张票
  * */
 public static void main(String[] args) {
     //实例化站台对象,并为每一个站台取名字
    Station station1=new Station("窗口1");
    Station station2=new Station("窗口2");
    Station station3=new Station("窗口3");
   // 让每一个站台对象各自开始工作
    station1.start();
    station2.start();
    station3.start();
}
}

Program run results:

窗口1卖出了第20张票
窗口2卖出了第19张票
窗口3卖出了第18张票
窗口3卖出了第17张票
窗口1卖出了第16张票
窗口2卖出了第15张票
窗口3卖出了第14张票
窗口1卖出了第13张票
窗口2卖出了第12张票
窗口2卖出了第11张票
窗口1卖出了第10张票
窗口3卖出了第9张票
窗口3卖出了第8张票
窗口1卖出了第7张票
窗口2卖出了第6张票
窗口3卖出了第5张票
窗口1卖出了第4张票
窗口2卖出了第3张票
窗口3卖出了第2张票
窗口1卖出了第1张票
票卖完了

You can see there's nothing wrong with the votes!

2. Two-person AB through an account A at the counter to withdraw money and B at the ATM to withdraw money!

Program analysis:

The amount of money is set to a static variable, and two people want to take the same object value. (i) Create a Bank class

package com.thread.demo.demo2;
import java.util.Objects;
public class Bank {
// 假设一个账户有1000块钱  
static double money = 1000;
// 柜台Counter取钱的方法  
private void Counter(double money) {
Bank.money -= money;
System.out.println("柜台取钱" + money + "元,还剩" + Bank.money + "元!");
}
// ATM取钱的方法  
private void ATM(double money) {
Bank.money -= money;
System.out.println("ATM取钱" + money + "元,还剩" + Bank.money + "元!");
}
//提供一个对外取款途径,防止直接调取方法同时取款时,并发余额显示错误
public synchronized void outMoney(double money, String mode) throws Exception{
if(money > Bank.money){
//校验余额是否充足
throw new Exception("取款金额"+money+",余额只剩"+Bank.money+",取款失败");
}
if(Objects.equals(mode, "ATM")){
ATM(money);
} else {
Counter(money);
}
}
}

(ii) Create a PersonA class

package com.thread.demo.demo2;
public class PersonA extends Thread {
Bank bank;
String mode;
public PersonA(Bank bank, String mode) {
this.mode = mode;
this.bank = bank;
}
while(bank.money >= 100){
try {
bank.outMoney(100, mode);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

(iii) Create a PersonB class

package com.thread.demo.demo2;
public class PersonB extends Thread {
Bank bank;
String mode;
public PersonB(Bank bank, String mode) {
this.bank = bank;
this.mode = mode;
}
public void run() {
while (bank.money >= 200) {
try {
bank.outMoney(200, mode);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

(iv) Create a calling class for the main method

package com.thread.demo.demo2;
/**
* 两个人AB通过一个账户A在柜台取钱和B在ATM机取钱
* */
public class MainClass {
public static void main(String[] args) {
Bank bank = new Bank();
// 实例化两个人,传入同一个银行的对象
PersonA a = new PersonA(bank, "Counter");
PersonB b = new PersonB(bank, "ATM");
a.start();
b.start();
}
}

Results:

 JAVA multithreaded programming instance1
You can see that it stops running when it's finished.

3. The problem of the turtle and rabbit race

Tortoise and Rabbit Race: 2000m
request:
(1) Rabbit every 0.1 seconds 5 meters speed, every 20 meters to rest 1 second;
(2) The tortoise runs 2 meters every 0.1 seconds without rest;
(3) One of them ran to the finish line and the other didn't run!
Programming ideas:
(1) Create an Animal Animal class, inherit Thread, write a runing abstract method, rewrite the run method, and call the runing method in the run method.
(2) Create Rabbit rabbits and Tortoise turtles to inherit animals
(3) Two subclasses override the running method
(4) The third requirement of this question relates to thread callbacks. You need to create a callback interface in the animal class to create a callback object.

(i) Create an Animal Animal class

package com.thread.demo.demo3;
public abstract class Animal extends Thread {
public int length = 2000;// 比赛长度
public abstract void runing();
@Override
public void run() {
super.run();
while (length > 0) {
runing();
}
}
// 在需要回调数据的地方(两个子类需要),声明一个接口
public static interface Calltoback {
public void win();
}
// 2.创建接口对象
public Calltoback calltoback;
}

(ii) Create a Rabbit rabbit class

package com.thread.demo.demo3;
public class Rabbit extends Animal {
public Rabbit() {
setName("兔子");
}
@Override
public void runing() {
//兔子速度
int dis = 5;
length -= dis;
System.out.println("兔子跑了" + dis + "米,距离终点还有" + length + "米");
if (length <= 0) {
length = 0;
System.out.println("兔子获得了胜利");
// 给回调对象赋值,让乌龟不要再跑了
if (calltoback != null) {
calltoback.win();
}
}
try {
if ((2000 - length) % 20 == 0) { // 每20米休息一次,休息时间是1秒
sleep(1000);
} else { //没0.1秒跑5米
sleep(100);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

(iii) Create a Tortoise turtle

package com.thread.demo.demo3;
public class Tortoise extends Animal {
public Tortoise() {
setName("乌龟");// Thread的方法,给线程赋值名字
}
// 重写running方法,编写乌龟的奔跑操作
@Override
public void runing() {
// 乌龟速度
int dis = 2;
length -= dis;
System.out.println("乌龟跑了" + dis + "米,距离终点还有" + length + "米");
if (length <= 0) {
length = 0;
System.out.println("乌龟获得了胜利");
// 让兔子不要在跑了
if (calltoback != null) {
calltoback.win();
          }
}
try {
sleep(100); //没0.1秒跑2米
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

(iv) Create a class that stops the animal thread, and here is the callback interface

package com.thread.demo.demo3;
import com.thread.demo.demo3.Animal.Calltoback;
public class LetOneStop implements Calltoback {
// 动物对象
Animal an;
// 获取动物对象,可以传入兔子或乌龟的实例
public LetOneStop(Animal an) {
this.an = an;
}
// 让动物的线程停止
@Override
public void win() {
// 线程停止
an.stop();
}
}

(v) Create a main method call class

package com.thread.demo.demo3;
public class MainClass {
/**
* 龟兔赛跑:2000米
*/
public static void main(String[] args) {
// 实例化乌龟和兔子
Tortoise tortoise = new Tortoise();
Rabbit rabbit = new Rabbit();
// 回调方法的使用,谁先调用calltoback方法,另一个就不跑了
LetOneStop letOneStop1 = new LetOneStop(tortoise);
// 让兔子的回调方法里面存在乌龟对象的值,可以把乌龟stop
rabbit.calltoback = letOneStop1;
LetOneStop letOneStop2 = new LetOneStop(rabbit);
// 让乌龟的回调方法里面存在兔子对象的值,可以把兔子stop
tortoise.calltoback = letOneStop2;
// 开始跑
tortoise.start();
rabbit.start();
}
}

Results:
 JAVA multithreaded programming instance2

4. Thread sample summary

(1) Code block lock is an important means to prevent data errors;

(2) Object unity is very important, this to think of the object's incoming problem, to operate the object can only be new once, other operations are carried out on this incoming object, in order to ensure data consistency, integrity and correctness.