線程小遊戲(一)

線程小遊戲(一)

什麼是程序、進程、線程、多線程?

程序:數據結構+編程語言+演算法+各種文件,程序儲存在硬體上(程序存儲在文件中,文件都存儲在硬碟上)

進程:正在運行的程序,在內存中運行(程序要運行時,進入內存,只有在內存中才能運行,進程是分配內存的基本單位)

線程:進程執行的基本單位,在cpu上運行(進程分成更小的線程,交給CPU,只有CPU才能計算)

但是線程運行會用到內存和寄存器,數據是存儲在內存中的,線程運行時需要CPU需要從內存中取數據,但是CPU的運行速度遠遠大於內存的運行速度,會造成CPU等待內存

的情況,為了規避這種情況,在線程啟動時就會將內存中的數據存儲到寄存器中(此時內存中和寄存器中各有一份數據,更改寄存器的數據不會影響內存中的數據,反之亦然)

多線程:多個線程並發運行。多線程具有不可控性,應用時一定要令其可控。

使用方法:

runnable:介面

run();線程運行方法,所有線程所需要執行的命令都寫在此方法中

Thread:類

run();

start();線程啟動方法,必須調用此方法才能執行多線程程序,否則與普通程序無區別

currentThread():當前線程運行情況

sleep():線程休眠,可延緩線程執行時間

-----------------------------------------------------------------------------------------------

現在我們來實現一個簡單的多線程程序,首先寫出一個畫板,在畫板上設置按鈕,點擊按鈕隨機畫出一個小球

package prf.com.thread180502;import java.awt.Color;import java.awt.FlowLayout;import java.awt.Graphics;import javax.swing.JButton;import javax.swing.JFrame;public class Draw { public void showUI(){ JFrame jf=new JFrame(""); jf.setSize(700, 700); jf.setDefaultCloseOperation(3); jf.setLocationRelativeTo(null); jf.getContentPane().setBackground(Color.WHITE); java.awt.FlowLayout flow =new FlowLayout(); jf.setLayout(flow); JButton jb=new JButton("畫點");//添加按鈕 jf.add(jb); jf.setVisible(true); drlistener dr1=new drlistener();//為按鈕添加監聽器 jb.addActionListener(dr1); Graphics g=jf.getGraphics();//取窗體的畫筆 dr1.setgr(g); dr1.setdr(jf); } public static void main(String[] args) { Draw dr=new Draw(); dr.showUI(); }}

監聽器(非多線程程序時):

package prf.com.thread180502;import java.awt.Color;import java.awt.Graphics;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.util.Random;import javax.swing.JFrame;public class drlistener implements ActionListener{ Graphics gr; JFrame jf; public void setgr(Graphics g) { gr = g; } public void actionPerformed(ActionEvent e) { int x=0,y=0; Random ra=new Random();//隨機生成初始坐標即小球出現的位置隨機 x=ra.nextInt(2000); y=ra.nextInt(1000); for(int i = y;i>=0;i--){ gr.setColor(Color.BLACK); gr.fillOval(x, i, 30, 30); try { Thread.sleep(50); } catch (InterruptedException e1) { e1.printStackTrace(); } gr.setColor(Color.WHITE);/*重畫當前小球之前的小球,使移動的 粗線條變成移動的小球*/ gr.fillOval(x, i, 30, 30); } } }

以上程序運行之後,點擊按鈕,會在窗體中隨機畫出一個小球,並向上移動,我們會發現,在小球未消失之前,我們無法再生成另一個小球且無法關閉程序。這是因為以上程序只是一個單線程程序,若是想要通過點擊按鈕生成多個小球該如何實現呢?這就涉及到了多線程問題。我們需要編寫一個多線程的類並修改監聽器代碼。

run()方法是線程運行方法,需要在run()方法中編寫需要的功能,我們將之前在監聽器中編寫的小球運動的代碼放入其中

package hdf;import java.awt.Color;import java.awt.Graphics;public class DrawThread extends Thread{//繼承Thread類 private int x,y; private Graphics gr; public DrawThread(int x, int y, Graphics g) {//構造函數傳參 super(); this.x = x; this.y = y; this.gr = g; } public void run(){ for(int i = y;i>=0;i--){ gr.setColor(Color.BLACK); gr.fillOval(x, i, 30, 30); try { Thread.sleep(50); } catch (InterruptedException e1) { e1.printStackTrace(); } gr.setColor(Color.WHITE); gr.fillOval(x, i, 30, 30); } } }

接下來修改原來的監聽器代碼

package hdf;import java.awt.Color;import java.awt.Graphics;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.util.Random;public class drlistener implements ActionListener{ Graphics gr; public void setgr(Graphics g){ gr=g; } public void actionPerformed(ActionEvent e) { int x=20,y=20; Random ra=new Random(); x=ra.nextInt(2000); y=ra.nextInt(1000); //ceate thread to start: DrawThread dt=new DrawThread(x,y,gr); dt.start();//注意,多線程調用的是start函數,不能調用run函數,否則與普通類無區別 }}

改變的是最後兩行代碼,只需要實例化一個DrawThread對象,調用方法即可。

一定注意調用的是start線程啟動函數,不能直接調用run函數,否則與普通類無區別。


實現以上基本功能之後,我們還可以額外添加一些功能,比如隨機生成小球的顏色、大小、移動速度、回彈功能等。

每一個小球是一個線程,若是生成的小球非常多,多到超出了CPU的承受能力,則會影響到程序的運行效率,因此我們希望實現多個小球由一個線程式控制制,以減輕CPU的負荷,詳細實現方法在線程小遊戲(二)中會說明。


推薦閱讀:

使用Unity2017開發MTV:一個Timeline和Cinemacine的實踐
protobuf在遊戲伺服器開發中的應用
兩個平均年齡十一歲的小男孩,做了兩款遊戲
《流放之路》——三個年輕人模仿暗黑2製造的神作
102_Entity 實體

TAG:遊戲開發 | 科技 |