Java multithreading ~~~ Synchronized adds parameters to implement independent code snippets
Sometimes we don't want to add the synchronized keyword before the entire method. This will make the call of the entire method slow.
Add the synchronized keyword to the code, and then speed up the execution efficiency of the method or code. Then there may be another situation:
Yes, we have two variables. Either of them can only be accessed by one variable at the same time, but the two variables can be accessed by both variables at the same time.
We need to use the sychronized method with parameters to achieve this requirement.
Here is an example of a simulated cinema ticket sales.
package com.bird.concursey.charpet2;public class Cinema {private long vacanciesCinema1;private long vacanciesCinema2;private final Object controlCinema1 = new Object();private final Object controlCinema2 = new Object();public Cinema() {vacanciesCinema1 = 20;vacanciesCinema2 = 20;}public boolean sellTickets1(int number) {synchronized (controlCinema1) {if(number < vacanciesCinema1) {vacanciesCinema1 -= number;return true;}else{return false;}}}public boolean sellTickets2(int number) {synchronized (controlCinema2) {if(number < vacanciesCinema2) {vacanciesCinema2 -= number;return true;}else{return false;}}}public boolean returnTicket1(int number) {synchronized (controlCinema1) {vacanciesCinema1 += number;return true;}}public boolean returnTicket2(int number) {synchronized (controlCinema2) {vacanciesCinema2 += number;return true;}}public long getVacanciesCinema1() {return vacanciesCinema1;}public void setVacanciesCinema1(long vacanciesCinema1) {this.vacanciesCinema1 = vacanciesCinema1;}public long getVacanciesCinema2() {return vacanciesCinema2;}public void setVacanciesCinema2(long vacanciesCinema2) {this.vacanciesCinema2 = vacanciesCinema2;}}
The following is the actual ticket sales class
package com.bird.concursey.charpet2;public class TicketOffice1 implements Runnable {private Cinema cinema;public TicketOffice1(Cinema cinema) {this.cinema = cinema;}@Overridepublic void run() {cinema.sellTickets1(3);cinema.sellTickets1(2);cinema.sellTickets2(2);cinema.returnTicket1(3);cinema.sellTickets1(5);cinema.sellTickets2(2);cinema.sellTickets2(2);cinema.sellTickets2(2);}}
package com.bird.concursey.charpet2;public class TicketOffice2 implements Runnable {private Cinema cinema;public TicketOffice2(Cinema cinema) {this.cinema = cinema;}@Overridepublic void run() {cinema.sellTickets2(2);cinema.sellTickets2(4);cinema.sellTickets1(2);cinema.sellTickets1(1);cinema.returnTicket2(2);cinema.sellTickets1(3);cinema.sellTickets2(2);cinema.sellTickets1(2);}public static void main(String[] args) {Cinema cinema = new Cinema();TicketOffice1 ticketOffice1 = new TicketOffice1(cinema);Thread thread1 = new Thread(ticketOffice1, "TicketOffice1");TicketOffice2 ticketOffice2 = new TicketOffice2(cinema);Thread thread2 = new Thread(ticketOffice2, "TicketOffice2");thread1.start();thread2.start();try {thread1.join();thread2.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.printf("Room 1 Vacancies: %d\n",cinema.getVacanciesCinema1());System.out.printf("Room 2 Vacancies: %d\n",cinema.getVacanciesCinema2());}}
We can see that each running will be the expected result, and through the singleton mode, we can control the access sequence of the two attributes very well.
Now our requirements are met.