synchronized同步的實現——多執行緒購票
同步的由來
當兩個或兩個以上的執行緒需要共享資源,必須使用某種方法來確定資源在某一時刻僅被一個執行緒佔用,達到此目的的過程叫做同步。(synchronized)
同步的實現
方法級同步(method-level synchronized)
synchronized void method( ) {
//同步的方法
}
物件級同步( block-level synchronized )
synchronized ( object ) {
//要同步的語句
}
應用場景舉例——多執行緒購票(同步方法)
package com.foot.lesson03;
public class TestSynchronized {
public static void main(String[] args) {
Tickets ticket = new Tickets();
BuyerThread bta = new BuyerThread(ticket);
bta.setName("售票點A");
BuyerThread btb = new BuyerThread(ticket);
btb.setName("售票點B");
bta.start();
btb.start();
}
}
class Tickets {
private int count;
public Tickets() {
this.count = 10;
}
// 購票操作
public synchronized String sell(String name) {
if (this.count > 0) {
count--;
return name + "購票成功,剩餘:" + count;
}
return "票已經售完!";
}
}
class BuyerThread extends Thread {
private Tickets ticket = null;
public BuyerThread(Tickets ticket) {
this.ticket = ticket;
}
@Override
public void run() {
while (true) {
String res = ticket.sell(getName());
System.out.println(res);
try {
sleep(1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
應用場景舉例——多執行緒購票(同步物件推薦使用)
package com.foot.lesson03;
public class TestSynchronized {
public static void main(String[] args) {
Tickets ticket = new Tickets();
BuyerThread bta = new BuyerThread(ticket);
bta.setName("售票點A");
BuyerThread btb = new BuyerThread(ticket);
btb.setName("售票點B");
bta.start();
btb.start();
}
}
class Tickets {
private Integer count;
public Tickets() {
this.count = 10;
}
// 購票操作
public String sell(String name) {
synchronized(this.count) {
if(this.count > 0) {
count--;
return name + "購票成功,剩餘:" + count;
} else {
return "票已經售完!";
}
}
}
}
class BuyerThread extends Thread {
private Tickets ticket = null;
public BuyerThread(Tickets ticket) {
this.ticket = ticket;
}
@Override
public void run() {
while (true) {
String res = ticket.sell(getName());
System.out.println(res);
try {
sleep(1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
執行結果如下
售票點B購票成功,剩餘:8
售票點A購票成功,剩餘:9
售票點A購票成功,剩餘:7
售票點B購票成功,剩餘:6
售票點A購票成功,剩餘:5
售票點B購票成功,剩餘:4
售票點B購票成功,剩餘:3
售票點A購票成功,剩餘:2
售票點B購票成功,剩餘:1
售票點A購票成功,剩餘:0
票已經售完!
票已經售完!
該執行結果,體現了多執行緒優先順序相同的情況產生的效果,取決於內部時間片的排程。
多執行緒購票修改
package com.foot.lesson4;
public class TestSynchronized {
public static void main(String[] args) {
Tickets ticket = new Tickets();
BuyerThread bt = null;
String[] str = {"A", "B", "C", "D", "E", "F"};
for (String string : str) {//多個地點同時購票
bt = new BuyerThread(ticket);
bt.setName("售票點" + string);
bt.start();
}
BuyerThread bta = new BuyerThread(ticket);
bta.setName("售票點1");
bta.start();
}
}
class Tickets {
private Integer count;
public Tickets() {
this.count = 100;
}
// 購票操作
public String sell(String name) {
synchronized(this.count) {
if(this.count > 0) {
count--;
return name + "購票成功,剩餘:" + count;
} else {
return null;
}
}
}
}
class BuyerThread extends Thread {
private Tickets ticket = null;
public BuyerThread(Tickets ticket) {
this.ticket = ticket;
}
@Override
public void run() {
while (true) {
String res = ticket.sell(getName());
if(null != res) {
System.out.println(res);
} else {
System.out.println("票已售完!");
break; //用於退出該執行緒
}
try {
sleep(1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
結果
體現了執行緒執行時是受時間片控制的。
售票點B購票成功,剩餘:98
售票點1購票成功,剩餘:93
售票點F購票成功,剩餘:94
售票點C購票成功,剩餘:97
售票點D購票成功,剩餘:96
售票點E購票成功,剩餘:95
售票點A購票成功,剩餘:99
售票點B購票成功,剩餘:92
售票點1購票成功,剩餘:91
售票點D購票成功,剩餘:90
售票點F購票成功,剩餘:86
售票點C購票成功,剩餘:87
售票點A購票成功,剩餘:88
售票點E購票成功,剩餘:89
售票點B購票成功,剩餘:85
售票點C購票成功,剩餘:83
售票點1購票成功,剩餘:84
售票點D購票成功,剩餘:82
售票點A購票成功,剩餘:79
售票點E購票成功,剩餘:81
售票點F購票成功,剩餘:80
售票點A購票成功,剩餘:78
售票點1購票成功,剩餘:77
售票點B購票成功,剩餘:72
售票點F購票成功,剩餘:73
售票點C購票成功,剩餘:75
售票點D購票成功,剩餘:76
售票點E購票成功,剩餘:74
售票點C購票成功,剩餘:70
售票點1購票成功,剩餘:65
售票點F購票成功,剩餘:67
售票點B購票成功,剩餘:66
售票點E購票成功,剩餘:68
售票點A購票成功,剩餘:69
售票點D購票成功,剩餘:69
售票點B購票成功,剩餘:64
售票點D購票成功,剩餘:58
售票點A購票成功,剩餘:60
售票點E購票成功,剩餘:63
售票點C購票成功,剩餘:59
售票點F購票成功,剩餘:60
售票點1購票成功,剩餘:62
售票點B購票成功,剩餘:57
售票點1購票成功,剩餘:56
售票點D購票成功,剩餘:54
售票點F購票成功,剩餘:55
售票點E購票成功,剩餘:51
售票點C購票成功,剩餘:52
售票點A購票成功,剩餘:53
售票點B購票成功,剩餘:50
售票點F購票成功,剩餘:47
售票點1購票成功,剩餘:46
售票點D購票成功,剩餘:45
售票點E購票成功,剩餘:47
售票點C購票成功,剩餘:49
售票點A購票成功,剩餘:47
售票點B購票成功,剩餘:43
售票點A購票成功,剩餘:40
售票點F購票成功,剩餘:39
售票點1購票成功,剩餘:41
售票點E購票成功,剩餘:42
售票點C購票成功,剩餘:44
售票點D購票成功,剩餘:38
售票點A購票成功,剩餘:37
售票點1購票成功,剩餘:35
售票點B購票成功,剩餘:36
售票點F購票成功,剩餘:34
售票點C購票成功,剩餘:33
售票點E購票成功,剩餘:31
售票點D購票成功,剩餘:32
售票點B購票成功,剩餘:30
售票點F購票成功,剩餘:27
售票點C購票成功,剩餘:28
售票點1購票成功,剩餘:29
售票點E購票成功,剩餘:26
售票點A購票成功,剩餘:25
售票點D購票成功,剩餘:24
售票點F購票成功,剩餘:23
售票點A購票成功,剩餘:22
售票點1購票成功,剩餘:21
售票點B購票成功,剩餘:20
售票點C購票成功,剩餘:19
售票點D購票成功,剩餘:18
售票點E購票成功,剩餘:17
售票點A購票成功,剩餘:16
售票點1購票成功,剩餘:14
售票點F購票成功,剩餘:13
售票點B購票成功,剩餘:15
售票點E購票成功,剩餘:10
售票點C購票成功,剩餘:11
售票點D購票成功,剩餘:12
售票點E購票成功,剩餘:9
售票點B購票成功,剩餘:4
售票點D購票成功,剩餘:3
售票點C購票成功,剩餘:5
售票點1購票成功,剩餘:6
售票點A購票成功,剩餘:7
售票點F購票成功,剩餘:8
售票點B購票成功,剩餘:2
票已售完!
票已售完!
票已售完!
售票點D購票成功,剩餘:1
售票點C購票成功,剩餘:0
票已售完!
票已售完!
票已售完!
票已售完!