標籤:synchronized java thread multithread
這幾天被線程弄暈了
特地惡補了一下java的線程知識
synchronized關鍵字是可以實現一個類對象同一時間只被一個線程調用,其他線程要調用這個對象只能等正在調用的線程結束或停止(一般會用在停止狀態,如果是結束的話直接用join()方法會更方便)才能獲得對象
synchronized使用方法一:鎖定對象方法
動手寫代碼,寫了一個類比買票的情境:
先寫一個Tickets類
class Tickets {public Tickets() {// TODO Auto-generated constructor stub}int total_tickets = 30;void sell_tickets(String thread_name) {synchronized (this) {total_tickets--;System.out.println(thread_name + " sell a ticket, remains "+ total_tickets);}}}設定一共有30張票,
sell_tickets(String thread_name)
會將線程名和剩餘張數列印出來,注意sell_tickets()裡面用了synchronized(this),表示這段代碼同一時間只能被一個線程調用
Thread counter1 = new Thread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubfor (int i = 0; i < 10; i++) {tickets.sell_tickets("1");try {Thread.sleep(50);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}});Thread counter2 = new Thread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubfor (int i = 0; i < 10; i++) {tickets.sell_tickets("2");try {Thread.sleep(50);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}});Thread counter3 = new Thread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubfor (int i = 0; i < 10; i++) {tickets.sell_tickets("3");try {Thread.sleep(50);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}});counter1.start();counter2.start();counter3.start();
建立1個Tickets類對象,3個counter線程,每個線程每隔一段時間就賣1張票,在Thread.sleep的時候就會讓別的等待線程獲得tickets.sell_ticket的使用權
結果如下:
1 sell a ticket, remains 293 sell a ticket, remains 282 sell a ticket, remains 271 sell a ticket, remains 262 sell a ticket, remains 253 sell a ticket, remains 242 sell a ticket, remains 231 sell a ticket, remains 223 sell a ticket, remains 212 sell a ticket, remains 201 sell a ticket, remains 193 sell a ticket, remains 182 sell a ticket, remains 171 sell a ticket, remains 163 sell a ticket, remains 152 sell a ticket, remains 143 sell a ticket, remains 131 sell a ticket, remains 122 sell a ticket, remains 113 sell a ticket, remains 101 sell a ticket, remains 92 sell a ticket, remains 81 sell a ticket, remains 73 sell a ticket, remains 62 sell a ticket, remains 51 sell a ticket, remains 43 sell a ticket, remains 32 sell a ticket, remains 23 sell a ticket, remains 11 sell a ticket, remains 0
可以看到,三個線程調用tickets對象並沒有發生衝突
synchronized使用方法二:線程中鎖定對象
這一次我們並不鎖定Tickets類方法
只做一般的定義
class Tickets {public Tickets() {// TODO Auto-generated constructor stub}int total_tickets = 30;void sell_tickets(String thread_name) {total_tickets--;System.out.println(thread_name + " sell a ticket, remains "+ total_tickets);}}
但我們線上程的runnable中使用synchronized將tickets對象同步
Thread counter1 = new Thread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubfor (int i = 0; i < 10; i++) {synchronized (tickets) {tickets.sell_tickets("1");}try {Thread.sleep(50);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}});同樣能實現同步的效果
java synchronized的運用