標籤: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多線程