爲此,我們舉個例子,假設有火車站有三個窗口,在賣火車票,總共只有5張票。每一個線程相當於一個窗口,分別售票
- <strong>package com.thread;
- class myThread extends Thread{
- private int ticketsCount=5;//一種有5張票
- private String name;//窗口,也即是線程的名字
- public myThread(String name){
- this.name=name;
- }
- @Override
- public void run() {
- while(ticketsCount>0) {
- //ticketsCount--;//如果還有票,就賣掉一張
- System.out.println(name+"有"+ticketsCount+"張票,賣了1一張票,剩餘票數爲:"+ --ticketsCount);
- //System.out.println(name+"賣了1一張票,剩餘票數爲:"+ticketsCount);
- }
- }
- }
- public class TicketsTread {
- public static void main(String args[]) {
- //創建三個線程,模擬三個窗口賣票
- myThread t1=new myThread("窗口1");
- myThread t2=new myThread("窗口2");
- myThread t3=new myThread("窗口3");
- //啓動這三個線程,也即是窗口開始賣票
- t1.start();
- t2.start();
- t3.start();
- }
- }
- </strong>
輸出爲:
這樣的結果說明了,每個窗口(線程)都賣了5張票,這是因爲創建了3個Thread對象,每個對象有自己的成員實例變量。
因爲每個線程,mt1,mt2,mt3分別是一個繼承了Thread類的一個對象,所以對象擁有其所屬類的私有或共有的成員變量或者成員方法,也就是說他們的變量,也即是票數ticketCount都是每個對象“自己”私有的,“各自爲營”,資源並不是共享的。 那麼,你就會看到,每個窗口都有5張票的情況咯。。
再使用runnable 來實現這個示例。
- package com.thread;
- class myThread_Runnable implements Runnable{
- private int ticketsCount=5;//一種有5張票
- public void run() {//如果給run方法加鎖,那麼會出現一個窗口會賣光所有票的現象
- while(ticketsCount>0) {
- ticketsCount--;//如果還有票,就賣掉一張
- System.out.println(Thread.currentThread().getName()+"賣了1一張票,剩餘票數爲:"+ticketsCount);
- }
- }
- }
- public class TicketsRunnable {
- public static void main(String args[]){
- myThread_Runnable mt=new myThread_Runnable();
- //創建三個線程,來模擬三個售票窗口
- Thread t1=new Thread(mt,"窗口1");
- Thread t2=new Thread(mt,"窗口2");
- Thread t3=new Thread(mt,"窗口3");
- //啓動這三個線程,也即是三個窗口,開始賣票
- t1.start();
- t2.start();
- t3.start();
- }
- }
上面這個是一個及其特殊的情況,線程(窗口)1一次性的使用了CPU並執行完了了run方法的所有代碼,然後進程結束。
下面這個是一般性的結果:
上面這個輸出就可以看出來,線程資源搶奪所導致的交叉執行。