初探Java多線程

來源:互聯網
上載者:User

標籤:opera   ack   繼承   read   資源釋放   back   draw   運行   font   

多線程是由Java提出的概念,那麼什麼是線程呢?這裡會涉及到幾個名字聽著很類似的東西:程式、線程、進程。

程式:儲存在磁碟上的一系列的檔案,包括可執行檔和不可執行檔。

進程:在記憶體中,每一個程式都會開啟一個進程。

線程:線程是進程的最小執行單元,線程在寄存器中,每一個線程需要消耗一定的cpu資源和512k到1M的記憶體資源。

多線程:也就是同一個程式中開啟多個線程就是多線程。

使用多線程有什麼樣的優勢呢?我們都知道在Java中,代碼是一句一句地往下執行的,上面的代碼沒有執行完畢,下面的另一段代碼就必須要等到上面的執行完畢,它才能夠執行。如果有程式要求必須在同一時間執行不同的代碼的話,單線程就顯然無法滿足要求了。另外由於多線程是幾個線程一同執行,所以可以大大的縮短一些需要大量重複執行的代碼的執行時間,打個比方,有一斤米要知道它有多少粒,如果一個人去數的話,不知道要數到什麼時候。但是如果多派幾個人去數的話,就能夠極大的提高效率,節約時間。現實生活是這個樣子,程式的執行更加如此。試問如果一個程式要得出結果需要個半分鐘,你還願意去等嗎?別說半分鐘了,幾秒鐘都不一定想等。所以多線程的作用就在於此了。多線程能夠提高程式的運行速度和執行效率,能夠同時執行一段代碼,完成單線程無法完成的事情。當然事情都是雙面性的,線程有其優點,自然也會有缺陷。前面已經說過線程是要消耗CPU和記憶體資源的,CPU和記憶體的資源是有限的。假設這樣的一種情況,有好幾個線程都要使用CPU,這時應該怎麼辦呢(線程的非同步)。解決方案當然有讓先拿到CPU的a線程先執行,其他的線程等待,a線程執行完畢後,釋放資源,然後其他的線程再次使用(線程的同步)。但是這樣又會產生新的問題,如果a線程和b線程同時執行了,a線程需要等待b線程的資源釋放才能夠繼續,而b線程同樣需要a線程的資源釋放才能夠繼續,這樣就會陷入一個死迴路中,誰也出不來(線程的死結)。當然我們並不會因為線程有缺陷就不用它,正相反線程的優勢是我們需要的,我們當然要用線程。

線程的使用有兩種方法:

繼承Thread類:Thread類實現了Runnable介面。常用的方法有:run()線程需要完成的事情放在run方法中;sleep()讓線程休眠的方法,參數是毫秒數;start()啟動線程的方法,然後start會執行run方法。

實現Runnable介面:run()線程需要完成的事情。

需要注意的是:Runnable介面中只有一個抽象的run()方法,它是沒有啟動線程的方法的,所以實現Runnable介面的類要想啟動線程,必須要執行個體化一個Thread對象,通過調用Thread對象的start方法才能夠正常的啟動一個線程。不知道大家有沒有這樣的疑惑:那就是為什麼需要調用start方法類啟動一個線程,直接調用run方法不行嗎?要解釋這個問題還需要搞清楚一件事情:那就是如果一個程式沒有使用線程,那麼這個程式中會不會存線上程。看下面的代碼:

public class Test {    public static void main(String[] args) {        System.out.println("main方法執行了");        System.out.println(Thread.currentThread());    }}

這段代碼輸出結果是這樣的:

main方法執行了
Thread[main,5,main]

這說明了什麼,只要我們程式中存在main方法,那麼該程式必然會存在一個線程。也就是說Java的虛擬機器會自動為main方法啟動一個線程。在Java中的線程是由Java的虛擬機器來調度的,我們自己是無法啟動線程的,所以需要一個start方法來告訴虛擬機器我們要啟動一個線程。換句話說,直接調用run方法,就是直接調用了run方法而已,是並沒有啟動線程的。

下面舉一個多線程的例子:

package com.cbs;import java.awt.Color;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.RenderingHints;import java.util.Random;import javax.swing.JFrame;/** * 線程類,畫小球 * @author CBS */public class ThreadDemo extends Thread {    private Graphics g;    private JFrame frame = null;    public ThreadDemo() {    }    public Graphics getG() {        return g;    }    public void setG(Graphics g) {        this.g = g;    }    public JFrame getFrame() {        return frame;    }    public void setFrame(JFrame frame) {        this.frame = frame;    }    public ThreadDemo(JFrame frame, Graphics g) {        this.frame = frame;        this.g = g;        System.out.println(frame);    }    Random r = new Random();    //隨機顏色    Color color = new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255));    public void run() {        Graphics2D g2d = (Graphics2D) g;//        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,//                RenderingHints.VALUE_ANTIALIAS_ON);//                int speedx = 3;//小球的移動速度        int speedy = 3;        int x = r.nextInt(frame.getWidth());        int y = r.nextInt(frame.getHeight());        while (true) {            if (x < frame.getWidth() && y < frame.getHeight()) {                g2d.setColor(Color.WHITE);                g2d.fillOval(x, y, 30, 30);                x += speedx;                y += speedy;                //判斷是否碰到邊界,如果是把小球反彈。                if (x > frame.getWidth()-20 && speedx > 0) {                    speedx = -speedx;                } else if (x < 10 && speedx < 0)                    speedx = -speedx;                if (y >frame.getHeight()-20 && speedy > 0)                    speedy = -speedy;                else if (y < 30 && speedy < 0)                    speedy = -speedy;                g2d.setColor(Color.GREEN);                g2d.fillOval(x, y, 30, 30);            }            try {                //線程休眠                this.sleep(30);            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}package com.cbs;/** * 主類,用來初始化一個介面 */import java.awt.Color;import java.awt.Graphics;import java.util.Random;import javax.swing.JFrame;public class Draw  {        public static void main(String[] args) {        Draw d=new Draw();        d.showUI();    }        public void showUI(){        JFrame jf=new JFrame();        jf.setTitle("Moving Point");        jf.setSize(500,500);        jf.setDefaultCloseOperation(3);        jf.setLocationRelativeTo(null);        jf.getContentPane().setBackground(Color.WHITE);                        jf.setVisible(true);                        Graphics g=jf.getGraphics();                Random r=new Random();        //隨機啟動多個線程        for(int i=0;i<=r.nextInt(10);i++){            ThreadDemo t=new ThreadDemo();            t.setFrame(jf);            t.setG(g);            t.start();        }    }    }
View Code

運行後就是幾個球在介面上到處亂撞。

ps:有點小bug ,我還不懂怎麼回事。

 

初探Java多線程

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.