1. 程式人生 > >二、創建進程和線程

二、創建進程和線程

管理 ces 關鍵字 計算器 遠程 重復調用 鍵盤 畫圖 end

1、在 Windows 操作系統中創建進程

  在 windows 操作系統中,我們創建一個進程通常就是打開某個應用軟件,這便在電腦中創建了一個進程。更原始一點的,我們在命令提示符中來做(我們以打開記事本這個進程為例):

  第一步:windows+R,輸入cmd,打開 cmd 命令提示符

      技術分享圖片

  第二步:在命令提示符中輸入 notepad,按 Enter 鍵便會彈出記事本應用軟件

      技術分享圖片

PS:常用的windows 應用軟件命令

    1、regedit:打開註冊表編輯器

    2、control:打開控制面板

    3、msconfig:打開系統配置

    4、gpedit.msc:打開本地組策略

    5、explorer:打開資源管理器

    6、taskmgr:任務管理器

    7、logoff:直接註銷計算機

    8、osk:打開屏幕鍵盤

    9、calc:打開計算器

    10、mspaint:調出畫圖軟件

    11、dxdiag:查看電腦詳細配置信息

    12、mstsc:打開遠程桌面連接

    13、systeminfo:查看計算機基本信息

    14、notepad:打開記事本

回到頂部

2、在 Java 中創建進程

第一種方法:通過 Runtime 類的 exec() 方法來創建進程

1 2 3 4 5 public class
Runtime extends Object ①、表示當前進程所在的虛擬機實例,每個Java應用程序都有一個Runtime類的Runtime ,允許應用程序與運行應用程序的環境進行接口。 ②、由於任何進程只會運行與一個虛擬機實例當中,即只會產生一個虛擬機實例(底層源碼采用 單例模式) ③、當前運行時可以從getRuntime方法獲得。

   技術分享圖片

  由上面源碼可以看到,構造器私有化了,即外部我們不能 new 一個新的 Runtime 實例,而內部給了我們一個獲取 Runtime 實例的方法 getRuntime() 。

通過 Runtime 類創建一個 記事本的 進程

1 2 3 4 5 6 7 8 9 public class ProcessTest { public static void main(String[] args) throws Exception { Runtime run = Runtime.getRuntime(); //打開記事本 run.exec("notepad"); } }

  

第二種方法:通過 ProcessBuilder 創建線程

1 2 3 public final class ProcessBuilder extends Object<br>①、此類用於創建操作系統進程。 ②、每個ProcessBuilder實例管理進程屬性的集合。 start()方法使用這些屬性創建一個新的Process實例。 start()方法可以從同一實例重復調用,以創建具有相同或相關屬性的新子進程。

技術分享圖片

1 2 3 4 5 6 7 8 9 public class ProcessTest { public static void main(String[] args) throws Exception { //打開記事本 ProcessBuilder pBuilder = new ProcessBuilder("notepad"); pBuilder.start(); } } 
回到頂部

3、在 Java 中創建線程

第一種方法:繼承 Thread 類

1 2 3 public class Thread extends Object implements Runnable  

步驟:1、定義一個線程類 A 繼承於 java.lang.Thread 類

   2、在 A 類中覆蓋 Thread 類的 run() 方法

   3、在 run() 方法中編寫需要執行的操作

   4、在 main 方法(線程)中,創建線程對象,並啟動線程

      創建線程類:A類 a = new A()類;

      調用 start() 方法啟動線程:a.start();

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package com.ys.thread; class Thread1 extends Thread{ @Override public void run() { for(int i = 0 ; i < 10 ;i++){ System.out.println("播放音樂"+i); } } } public class ThreadTest { public static void main(String[] args) { for(int i = 0 ; i < 10 ; i++){ System.out.println("玩遊戲"+i); if(i==5){ Thread1 th1 = new Thread1(); th1.start(); } } } }

  結果:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 玩遊戲0 玩遊戲1 玩遊戲2 玩遊戲3 玩遊戲4 玩遊戲5 玩遊戲6 玩遊戲7 玩遊戲8 玩遊戲9 播放音樂0 播放音樂1 播放音樂2 播放音樂3 播放音樂4 播放音樂5 播放音樂6 播放音樂7 播放音樂8 播放音樂9

  註意:我們看結果,並不是出現 5 個先打遊戲,然後在播放音樂,這是線程調度的結果,兩個線程同時在爭搶 CPU 的資源,即最後的結果,前面5個打遊戲的必然先出現的,後面的啥時候出現播放音樂就看 CPU 怎麽調度了,這是隨機的。我們不能幹涉。

第二種方法:實現 Runnable 接口

1 2 @FunctionalInterface public interface Runnable

  

1、Runnable接口應由任何類實現,其實例將由線程執行。 該類必須定義一個無參數的方法,稱為run 。
2、該接口旨在為希望在活動時執行代碼的對象提供一個通用協議。此類整個只有一個 run() 抽象方法

技術分享圖片

步驟:1、定義一個線程類 A 實現於 java.lang.Runnable 接口(註意:A類不是線程類,沒有 start()方法,不能直接 new A 的實例啟動線程)

   2、在 A 類中覆蓋 Runnable 接口的 run() 方法

   3、在 run() 方法中編寫需要執行的操作

   4、在 main 方法(線程)中,創建線程對象,並啟動線程

      創建線程類:Thread t = new Thread( new A類() ) ;

      調用 start() 方法啟動線程:t.start();

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Runnable1 implements Runnable{ @Override public void run() { for(int i = 0 ; i < 10 ;i++){ System.out.println("播放音樂"+i); } } } public class RunnableTest { public static void main(String[] args) { for(int i = 0 ; i < 10 ; i++){ System.out.println("玩遊戲"+i); if(i==5){ Thread th1 = new Thread(new Runnable1()); th1.start(); } } } }

  

第三種方法:使用匿名內部類創建線程

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public static void main(String[] args) { for(int i = 0 ; i < 10 ; i++){ System.out.println("玩遊戲"+i); if(i==5){ new Thread(new Runnable() { @Override public void run() { for(int i = 0 ; i < 10 ;i++){ System.out.println("播放音樂"+i); } } }).start(); } } }

  

註意:

1、啟動線程是調用 start() 方法,而不是 調用 run() 方法。

  解析:run()方法:在本線程內調用run()方法,和其他方法沒有什麽區別,可以重復多次調用;

     start()方法:啟動一個線程,實際上還是調用該Runnable對象的run()方法。

     打開 Thread 類的源碼,start()方法裏面有一句:

        private native void start0(); //native 關鍵字:本地程序調用    

    native關鍵字指的是Java本地接口調用,即是使用Java調用本地操作系統的函數功能完成一些特殊的操作,而這樣的代碼開發在Java中幾乎很少出現,因為Java的最大特點是可移植性,如果一個程序 只能在固定的操作系統上使用,那麽可移植性就將徹底喪失,多線程的實現一定需要操作系統的支持,那麽start0()方法實際上就和抽象方法很類似,沒有方法體,而是交給JVM 去實現,即在windows下的JVM可能使用A方法實現start0(),在linux下的JVM可能使用B方法實現start0(),在調用時並不會關心具體是何方式實現了start0()方法,只會關心最終的操作結果,交給 JVM去匹配了不同的操作系統。

2、不能多次啟動同一個線程,即多次調用 start() 方法,只能調用一次,否則報錯:

  技術分享圖片

二、創建進程和線程