Java ticket selling task_ Detailed implementation of multithreading

Java ticket selling task_ Detailed implementation of multithreading

Title Review: the Ministry of Railways has issued a ticket sales task, which requires 1000 tickets to be sold and three windows to be sold. Please write a multi-threaded program to simulate this effect.

i. window 001 is selling ticket 1000

ii. Window 001 is selling ticket 999

iii. window 002 is selling ticket 998

​ iv. ...

v. window 002 is selling the first ticket

vi. tickets sold

1, Pay attention to details:

Question 1: three threads sold 1000 tickets, a total of 3000 tickets
Reason: three threads represent three objects, and there are three member variables (three ticket s)
Solution: make the member variable ticket static variable, because the static variable is shared by all objects of this class
Question 2: some tickets sold heavy
Cause: switch to another thread after output, ticket variable does not have –, so data error is caused
Solution: lock to ensure output and ticket - switch to other threads after running
Question 3: negative votes
Reason: ticket zero point, three threads may enter
Solution: judge again in synchronization code
synchronized synchronization lock, mutex lock:
Note: to be mutually exclusive, multiple threads must use the same lock object
Synchronization code block:
Synchronized (lock object) {/ / lock
​ … Code
} / / unlock
Synchronization method:
Lock lock:















2, Inherit Thread interface implementation

2.1 first solution: synchronous code block

/*synchronized Synchronization lock and mutual exclusion lock:
 * 	Note: to be mutually exclusive, multiple threads must use the same lock object
		 * 	Synchronization code block:
		 * 		synchronized(Lock object){//Lock
		 * 			...code...
		 * 		}//Unlock
		 * /
public static void main(String[] args) {
		myThread01 t1 = new myThread01("Window 1");
		myThread01 t2 = new myThread01("Window 2");
		myThread01 t3 = new myThread01("Window three");
		t1.start();
		t2.start();
		t3.start();
	}
}
class myThread01 extends Thread{
	private static int tecket = 1000;
	private static Object obj= new Object();
	public myThread01(String name) {
		super(name);
	}
	@Override
	public void run() {
		while(tecket>0){
			synchronized (obj) {
			if(tecket>0){
			System.out.println(Thread.currentThread().getName()+"Sales in progress"+tecket+"Tickets");
			tecket--;
			}else if(tecket==0){
			System.out.println(Thread.currentThread().getName()+"Tickets sold out");
			}else{
			System.out.println(Thread.currentThread().getName()+"Tickets sold out");
			}	
			}
		}
	}

2.2 second solution: synchronization method

public static void main(String[] args) {
		/**
		 * 	Synchronization method:
		 * 		Lock object -- this
		 * 		public synchronized void method01(){}
		 * 		Lock object -- bytecode file object of this class
		 * 		public synchronized static void method02(){}
		 */
		myThread01 t1 = new myThread01("Window 1");
		myThread01 t2 = new myThread01("Window 2");
		myThread01 t3 = new myThread01("Window three");
		t1.start();
		t2.start();
		t3.start();
	}
}
class myThread02 extends Thread{
	private static int tecket = 1000;
	private static Object obj= new Object();
	public myThread02(String name) {
		super(name);
	}
	@Override
	public void run() {
		while(tecket>0){
			method01();
		}
	}
public synchronized static void method01(){
	synchronized (obj) {
		if(tecket>0){
		System.out.println(Thread.currentThread().getName()+"Sales in progress"+tecket+"Tickets");
		tecket--;
		}else if(tecket==0){
		System.out.println(Thread.currentThread().getName()+"Tickets sold out");
		}else{
		System.out.println(Thread.currentThread().getName()+"Tickets sold out");
		}	
		}
	}

2.3 the third solution: lock lock


public class Thread_03 {
	public static void main(String[] args) {
		myThread01 t1 = new myThread01("Window 1");
		myThread01 t2 = new myThread01("Window 2");
		myThread01 t3 = new myThread01("Window three");
		t1.start();
		t2.start();
		t3.start();
	}
}
/*
 * * Lock Lock:
 * 	Lock lock = new ReentrantLock();
 */
class myThread03 extends Thread{
	private static int tecket = 1000;
	//Create lock lock object
	private static Lock lock = new ReentrantLock();
	public myThread03(String name) {
		super(name);
	}
	@Override
	public void run() {
		while(tecket>0){
			lock.lock();//Lock
			if(tecket>0){
			System.out.println(Thread.currentThread().getName()+"Sales in progress"+tecket+"Tickets");
			tecket--;
			}else if(tecket==0){
			System.out.println(Thread.currentThread().getName()+"Tickets sold out");
			}else{
			System.out.println(Thread.currentThread().getName()+"Tickets sold out");
			}	
			lock.unlock();//Unlock
		}
	}
}

2.4 comparison of two locking modes: synchronized vs lock (important)

		Difference 1:
	 *synchronized lock will lock and unlock automatically
	 *Lock lock must be locked and unlocked manually
	 *Difference 2:
	 *Locks at the synchronized JVM level
	 *Locks at the Lock API level
	 *Difference 3:
	 *Lock has a read-write lock

3, Runnable interface implementation

3.1 implementation of the first method: synchronous code block

 public class Runnable_01 {
	public static void main(String[] args) {
		 myRunnable01 task = new myRunnable01();
		 Thread task1 = new Thread(task,"Window 1");
		 Thread task2 = new Thread(task,"Window 2");
		 Thread task3 = new Thread(task,"Window three");
		 task1.start();
		 task2.start();
		 task3.start();
	}
}
class myRunnable01 implements Runnable{
	private int ticket = 1000;
	private Object obj = new Object();
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(ticket > 0){
//			synchronized("abc"){
//			synchronized(Object.class){
//			synchronized(obj){
			synchronized(this){
				if(ticket > 0){
					System.out.println(Thread.currentThread().getName() + "Sales in progress" + ticket + "Tickets");
					ticket--;
					if(ticket == 0){
						System.out.println(Thread.currentThread().getName() + "Tickets sold out");
					}
				}else{
					System.out.println(Thread.currentThread().getName() + "Tickets sold out");
				}
			}
		}
	}
}

3.2 implementation of the second method: synchronization method

p
public class Runnable_02 {
	public static void main(String[] args) {
		 myRunnable02 task = new myRunnable02();
		 Thread task1 = new Thread(task,"Window 1");
		 Thread task2 = new Thread(task,"Window 2");
		 Thread task3 = new Thread(task,"Window three");
		 task1.start();
		 task2.start();
		 task3.start();
	}
}
class myRunnable02 implements Runnable{
	private static int ticket = 1000;
	private Object obj = new Object();
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(ticket > 0){
//			synchronized("abc"){
//			synchronized(Object.class){
//			synchronized(obj){
			methodR01();
		}
	}
	public  synchronized void methodR01(){
			if(ticket > 0){
				System.out.println(Thread.currentThread().getName() + "Sales in progress" + ticket + "Tickets");
				ticket--;
				if(ticket == 0){
					System.out.println(Thread.currentThread().getName() + "Tickets sold out");
				}
			}else{
				System.out.println(Thread.currentThread().getName() + "Tickets sold out");
			}
		}
	}

3.3 the third way: lock lock


public class Runnable_03 {
	public static void main(String[] args) {
		 myRunnable03 task = new myRunnable03();
		 Thread task1 = new Thread(task,"Window 1");
		 Thread task2 = new Thread(task,"Window 2");
		 Thread task3 = new Thread(task,"Window three");
		 task1.start();
		 task2.start();
		 task3.start();
	}
}
class myRunnable03 implements Runnable{
	private int ticket = 1000;
	private Lock lock = new ReentrantLock();
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(ticket > 0){
//			synchronized("abc"){
//			synchronized(Object.class){
//			synchronized(obj){
			lock.lock();
				if(ticket > 0){
					System.out.println(Thread.currentThread().getName() + "Sales in progress" + ticket + "Tickets");
					ticket--;
					if(ticket == 0){
						System.out.println(Thread.currentThread().getName() + "Tickets sold out");
					}
				}else{
					System.out.println(Thread.currentThread().getName() + "Tickets sold out");
			}
				lock.unlock();
		}
	}
}

4, The problem of additional philosophers' eating


public class Test01 {
	public static void main(String[] args) {
		//deadlock
		//Do not lock nesting as much as possible
		//Thread 1
		new Thread(new Runnable() {
			@Override
			public void run() {
				synchronized (KuaiZi.a) {
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					
					synchronized(KuaiZi.b){
						System.out.println("Philosopher 1 has dinner");
					}
				}
			}
		}).start();

		//Thread 2
		new Thread(new Runnable() {
			@Override
			public void run() {
				synchronized (KuaiZi.b) {
					
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					
					synchronized(KuaiZi.a){
						System.out.println("Philosopher 2 has dinner");
					}
				}
			}
		}).start();
	}
}
class KuaiZi{
	public static Object a = new Object();
	public static Object b = new Object();
}

Keywords: Java Windows jvm

Added by JustLikeIcarus on Sun, 14 Jun 2020 11:38:42 +0300