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(); }