【Java】繼承 Thread 和 實現 Runnable 區別
繼承 Thread VS 實現 Runnable 區別

從java的設計來看,通過繼承Thread或者實現Runnable接口來創建線程本質上沒有區別,從jdk幫助文檔可以看到Thread類本身就實現了Runnable接口
實現Runnable接口方式更加適合多個線程共享一個資源的情況,并且避免了單繼承的限制,建議使用Runnable。
【售票系統】,模擬三個售票窗口同時售票100張,分別使用繼承 Thread和實現 Runnable方式,并分析有什么問題?
繼承 Thread 方式實現,會出現“超賣”的問題
public class SellTicket { public static void main(String[] args) { SellTicket01 sellTicket01 = new SellTicket01(); SellTicket01 sellTicket02 = new SellTicket01(); SellTicket01 sellTicket03 = new SellTicket01(); //這里會出現票數超賣的現象 sellTicket01.start(); sellTicket02.start(); sellTicket03.start(); } } //使用繼承 Thread 方式 class SellTicket01 extends Thread { private static int ticketNum = 100; //讓多個線程共享 ticketNum @Override public void run() { while (true) { if (ticketNum <= 0) { System.out.println("售票結束..."); break; } //休眠50毫秒,模擬休息時間 try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("窗口 " + Thread.currentThread().getName() + " 售出一張票" + " 剩余票數" + (--ticketNum)); } } }
原因介紹如下:
當總票數最后只剩下 1 張時,三個窗口同時售賣一張票的情況下,就會導致票數變成 -2 張的情況
實現 Runnable 接口的方式來實現,就可以避免出現“超賣”的現象,因為這三個線程(窗口)指向同一個對象(sellTicket02)
public class SellTicket { public static void main(String[] args) { SellTicket02 sellTicket02 = new SellTicket02(); new Thread(sellTicket02).start(); //第1個線程-窗口 new Thread(sellTicket02).start(); //第2個線程-窗口 new Thread(sellTicket02).start(); //第3個線程-窗口 } } class SellTicket02 implements Runnable { private int ticketNum = 100; @Override public void run() { while (true) { if (ticketNum <= 0) { System.out.println("售票結束..."); break; } //休眠50毫秒,模擬休息時間 try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("窗口 " + Thread.currentThread().getName() + " 售出一張票" + " 剩余票數" + (--ticketNum)); } } }
Java
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。