案例內容
使用多線程完成10個窗口銷售1000張票
錯誤做法
package com.inspire.juc.c_024_FromVectorToQueue;
import java.util.ArrayList;
import java.util.List;
public class TicketSeller1 {
static List<String> tickets=new ArrayList<>();
static {
for(int i=0;i<=10000;i++){
tickets.add("票編號"+i);
}
}
public static void main(String[] args) {
for(int i=0;i<10;i++){
new Thread(()->{
while(tickets.size()>0){
System.out.println("銷售了:"+tickets.remove(0));
}
}).start();
}
}
}
正確做法
package com.inspire.juc.c_024_FromVectorToQueue;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class TicketSeller3 {
static List<String> tickets=new ArrayList<>();
static {
for(int i=0;i<=1000;i++){
tickets.add("票編號"+i);
}
}
public static void main(String[] args) {
for(int i=0;i<10;i++){
new Thread(()->{
while (true){
synchronized (tickets){
if(tickets.size()<=0){
break;
}
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("銷售了:"+tickets.remove(0));
}
}
}).start();
}
}
}
優化後的做法
package com.inspire.juc.c_024_FromVectorToQueue;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
public class TicketSeller4 {
static Queue<String> tickets=new ConcurrentLinkedQueue<>();
static {
for(int i=0;i<1000;i++){
tickets.add("票編號:"+i);
}
}
public static void main(String[] args) {
for(int i=0;i<10;i++){
new Thread(()->{
while(true){
String s=tickets.poll();
if(s==null){
break;
}
System.out.println("銷售了:"+s);
}
}).start();
}
}
}
附
Queue是ASC鎖(無鎖),因此效率更高