Java中併發、線程之類的操做很重要,不過概念上有時候常常搞混。這裏由於以前在瀏覽的時候隨手記錄了一下,感受對於捋清線程、併發有必定幫助,特意記錄了一下。java
上代碼來講話:安全
例子一:多線程
public class ThreadErrorDemo { public static void main(String args[]){ //列表 final List<String> tickets = new ArrayList<String>(); //初始化 for(int i=0;i<10000;i++){ tickets.add("ticket"+i); } //退ticket Thread returnThread = new Thread(){ public void run(){ while(true){ tickets.add("ticket"+new Random().nextInt()); } } }; //售ticket Thread saleThread = new Thread(){ public void run(){ for(String ticket:tickets){ tickets.remove(ticket); } } }; //啓動線程 returnThread.start(); //啓動線程 saleThread.start(); } }
上述例子一是錯誤的多線程例子.這個寫法是會出問題的,執行的時候會報java.util.ConcurrentModificationException異常,這個例子是混淆了線程安全和同步修改異常併發
再來看一個例子二:dom
public class ThreadArrayListDemo { public static void main(String args[]){ //列表 final List<String> tickets = new ArrayList<String>(); //初始化 for(int i=0;i<10000;i++){ tickets.add("ticket"+i); } //10個窗口 for(int i=0;i<10;i++){ new Thread(){ public void run(){ while(true){ System.out.println(Thread.currentThread().getId()+"——"+tickets.remove(0)); } } }.start(); } } }
這個例子是正確理解了多線程的用法,可是又很遺憾ArrayList是線程不安全的.線程
最後來看例子三:code
public class ThreadVectorDemo { public static void main(String args[]){ final AtomicInteger count = new AtomicInteger(0); //列表 final List<String> tickets = new Vector<String>(); //初始化 for(int i=0;i<100;i++){ tickets.add("ticket"+i); } //10個窗口 for(int i=0;i<10;i++){ new Thread(){ public void run(){ while(true){ if(tickets.size()>0){ count.incrementAndGet(); System.out.println(Thread.currentThread().getId()+"——"+tickets.remove(0)); }else{ System.out.println("執行計數:"+count.get()); System.exit(0); } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } } }
Ok,能夠了,這個例子是正確理解了多線程的用法,這裏使用Vector代碼上一個的ArrayList來實現線程安全。rem
理解上應該是多個線程,若是作的是一樣的一種操做,上面就是10個窗口線程都執行售出操做,而併發的狀況應該是,每一個窗口中不單單能夠售出,也能夠退掉、換路程之類的操做,這樣就變成一個窗口(線程)中,多種操做了。get