j2ee(5) 線程

來源:互聯網
上載者:User

標籤:set   不能   避免   另一個   print   方法   name   代碼   儲存   

1.理清概念 並行與並發:    *並行:多個cpu執行個體或者多台機器同時執行一段處理邏輯,是真正的同時。    *並發:通過cpu調度演算法,讓使用者看上去同時執行,實際上從cpu操作層面不是真正的同時。並發往往在情境中有公用的資源,那麼針對這個公用的資源往往產生瓶頸,我們會用TPS或者QPS來反應這個系統的處理能力。            2.線程建立    * 繼承thread類建立多線程            public class Example01 {            public static void main(String[] args) {                                MyThread myThread = new MyThread();        //建立線程 MyThread 的線程對象                myThread.start();                        //開啟線程                                while(true){                    System.out.println("main 方法在運行");                }                                            }        }        class MyThread extends Thread{                        public void run(){                while (true){                    System.out.println("MyThread 類的 run()方法在運行");                }            }        }            * 實現Runnable介面建立線程            public class Example01 {            public static void main(String[] args) {                                MyThread myThread = new MyThread();        //建立線程 MyThread 的線程對象                Thread thread = new Thread(myThread);   //建立線程對象                thread.start();                          //開啟線程,執行線程中的run()方法                                while(true){                    System.out.println("main 方法在運行");                }                            }        }        class MyThread implements Runnable{                        public void run(){                while (true){                    System.out.println("MyThread 類的 run()方法在運行");                }            }        }                    * 兩種實現多線程方式的對比分析,實現Runnable介面相對於繼承Thread類有如下顯著的好處        1.可以避免由於java的單繼承帶來的局限。java不支援多繼承(子類不能有多個父類),其他類的子類不能用繼承Thread類的方式,只能採用實現Runnable介面的方式        2.適合多個相同程式碼的線程去處理同一個資源的情況,把線程同程式碼、資料有效分離            * 後台進程      --如果某個線程對象在啟動之前調用了setDaemon(true)語句,這個線程就變成一個後台進程      --當前台線程結束後,JVM會通知後台線程      --進程中只有後台線程運行時,進程會結束            3.線程的調度    * 線程的優先順序      --static int MAX_PRIORITY        表示線程的最高優先順序 相當於值10      --static int MIN_PRIORITY        表示線程的最低優先順序 相當於值1      --static int NORM_PRIORITY    表示線程的普通優先順序 相當於值5        * 線程休眠      --Thread.sleep()            * 線程讓步      --Thread.yield()            * 線程插隊      --join()    4.多線程同步    * 安全執行緒      --多個線程同時去訪問同一個資源時,易引發安全問題。            *同步代碼塊        class Ticket1 implements Runnable{                        private int tickets = 10;            //定義變數 賦值                Object lock = new Object();            //定義任意一個對象,用作同步代碼塊的鎖                        public void run(){                                while (true){                    synchronized(lock){            //定義同步代碼塊                                                try {                            Thread.sleep(2000);                        } catch (InterruptedException e) {                            e.printStackTrace();                        }                                                if(tickets >0){                            System.out.println(Thread.currentThread().getName()+"---賣出的票---"+tickets--);                        }else{                            break;                        }                    }                }                            }        }        public class Example01 {            public static void main(String[] args) {                Ticket1 ticket = new Ticket1();                //建立 Ticket1 對象                 //建立並開啟四個線程                new Thread(ticket,"線程1").start();                        new Thread(ticket,"線程2").start();                new Thread(ticket,"線程3").start();                new Thread(ticket,"線程4").start();            }        }                *同步方法            class Ticket1 implements Runnable{                        private int tickets = 10;            //定義變數 賦值                public void run(){                while (true){                        saleTicket();                        if(tickets <=0){                            break;                        }                }            }                        //定義一個同步方法saleTicket()            private synchronized void saleTicket(){                if(tickets > 0){                    try {                        Thread.sleep(2000);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                                System.out.println(Thread.currentThread().getName()+"---賣出的票---"+tickets--);                }            }            }        public class Example01 {            public static void main(String[] args) {                Ticket1 ticket = new Ticket1();                //建立 Ticket1 對象                 //建立並開啟四個線程                new Thread(ticket,"線程1").start();                        new Thread(ticket,"線程2").start();                new Thread(ticket,"線程3").start();                new Thread(ticket,"線程4").start();            }        }            *鎖死問題        5.多線程通訊    *問題引入:假設有兩個線程同時去操作同一個儲存空間,其中一個線程負責向儲存空間中存入資料,另一個線程負責取出資料。        --資料存放區類        public class Storage {            //資料存放區數組            private int[] cells = new int[10];                        //inPos 表示存入時數組下標,outPos表示取出時數組下標            private int inPos,outPos;                        //定義一個put()方法向數組中存入資料                        public void put(int num){                cells[inPos] = num;                System.out.println("在cells["+inPos+"]中放入資料--"+cells[inPos]);                inPos++;                if(inPos == cells.length)                    inPos = 0;                //當inPos為數組長度時 將其置為0            }                        //定義一個get()方法從數組中取出資料            public void get(){                int data = cells[outPos];                System.out.println("在cells["+outPos+"]中取出資料--"+data);                outPos++;                if(outPos == cells.length)                    outPos = 0;                //當outPos為數組長度時 將其置為0            }                }    --資料存取類        public class Input implements Runnable {                        private Storage st;                        private int num;                        Input (Storage st){                //通過構造方法接收一個Storage對象                this.st= st;            }            @Override            public void run() {                while(true){                    st.put(num++);            //將num存入數組,每次存入後num自增                }            }        }        public class Output implements Runnable {                        private Storage st;            Output(Storage st){                    //通過構造方法接收一個Storage對象                this.st = st;            }                        @Override            public void run() {                while(true){                    st.get();                }            }        }            --建立線程            public class ExampleTest02 {            public static void main(String[] args) {                                Storage st = new Storage();                //建立資料存放區對象                Input input = new Input(st);            //建立Input對象傳入Storage對象                Output output=new Output(st);            //建立Output對象傳入Storage對象                                new Thread(input).start();                //開啟新線程                new Thread(output).start();                //開啟新線程            }        }                * 問題解決:測試發現上述存取進程是隨機的,未按照順序輪流執行。如需按照一定順序輪流執行,此時需要讓進程間進行通訊    --在Object類中提供了wait(),notify(),notifyAll()方法用於解決線程間的通訊問題,因為Java中的所有類都是Object類的子類或間接子類,因此任何類的執行個體對象都可以直接使用這些方法。    --void wait()  使當前線程放棄同步鎖並進入等待,直到其他線程進入此同步鎖,並調用notify()或notifyAll()方法喚醒該線程為止    --void notify() 喚醒此同步鎖上等待的第一個調用wait()方法的線程    --void notifyAll() 喚醒此同步鎖上調用wait()方法的所有線程        public class Storage {                private int[] cells = new int[10];    //資料存放區數組                private int inPos,outPos;            //inPos 表示存入時數組下標,outPos表示取出時數組下標            private int count;                    //存入或取出資料的數量                        //定義一個put()方法向數組中存入資料            public synchronized void put(int num){                                //存入資料如果等於cells的長度,此線程等待                while(count == cells.length){                    try {                        this.wait();                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }                cells[inPos] = num;                System.out.println("在cells["+inPos+"]中放入資料--"+cells[inPos]);                inPos++;                if(inPos == cells.length)                    inPos = 0;                //當inPos為數組長度時 將其置為0                                count++;                this.notify();            }                        //定義一個get()方法從數組中取出資料            public synchronized void get(){                                while(count == 0){         //如果count為0 此線程等待                    try {                        this.wait();                    } catch (InterruptedException e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                    }                }                int data = cells[outPos];                System.out.println("在cells["+outPos+"]中取出資料:"+data);                cells[outPos] = 0;                outPos++;                if(outPos == cells.length)                    outPos = 0;                //當outPos為數組長度時 將其置為0                count--;                this.notify();            }                }            注意:如果wait(),notify(),notifyAll()方法調用者不是同步鎖對象,JVM會拋出 java.lang.IllegalMonitorStateException            

 

j2ee(5) 線程

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.