这是一个买票的问题
public class TicketSeller2 { static Vector<String> tickets = new Vector<>(); 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(() -> {
//这里的size()和remove()都是原子性的,但问题会出现在size()和remove()之间 while (tickets.size() > 0) { // 展现代码问题方法,将线程沉睡一会
//当代吗醒来时,会有可能大量的高并发去争夺最后一张票,从而导致问题 try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("销售了:" + tickets.remove(0)); } }).start(); } } }
解决方案:
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 (tickets.size() > 0) { // sychronized 保证了原子性 synchronized (tickets) { System.out.println("销售了:" + tickets.remove(0)); } } }).start(); } } }
3.优化
public class TicketSeller4 { static Queue<String> queue = new ConcurrentLinkedQueue<>(); static { for (int i = 0; i < 1000; i++) { queue.add("票-" + i); } } public static void main(String[] args) { for (int i = 0; i < 10; i++) { new Thread(() -> { while (true) { String t = queue.poll(); // 取出头,拿不到就是空值 if (t == null) { break; } System.out.println("销售了:" + t); } }).start(); } } }