程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> 走近並發編程之一 進程和線程,走近並發編程線程

走近並發編程之一 進程和線程,走近並發編程線程

編輯:JAVA綜合教程

走近並發編程之一 進程和線程,走近並發編程線程


並發與並行,進程與線程不僅是操作系統中及其重要的概念,也是並發編程入門

必須要理解的核心知識。

順序編程:程序中的所有事物在任意時刻都只能執行一個步驟

並發:在同一時間段內,需要處理多個任務,而在每個時間點又只能處理一個,這就是並發。

假設我們要把多個任務分配給處理機,如果這台機器有多個處理器,顯然可以同時執行這些任務,這就是並行

不同於並行,並發的目的旨在最大限度的提高程序在單處理器上的效率。前者是在物理上的同時發生,而並發是在邏輯上的同時發生。如圖,如果要在同一個時間段內處理task1, task2,需要在任務之間來回切換,完成並發執行

圖:一個簡單並發的例子

 

    2.  Java的多線程和並發性

Java是一種多線程語言,並發是Java非常重要的高級特性之一。對於分布式系統甚至於web系統的開發者來說,學會高效的並發編程至關重要。例如,web系統是Java的常見應用之一,最基本的java web庫類 Servlet就具備天生的多線程特性,圖形用戶界面類似於Swing和SWT也具備線程安全的機制。如果你不了解並發,你很難很好的使用好這些工具。

 

    3.  進程和線程

進程可以定義為一個執行中的程序的實例,進程擁有自己的地址空間,以及用來記錄進程的進程控制塊(PCB)。想到實現並發,人們最先想到的便是通過進程。在多任務操作系統中,CPU會周期性地從一個進程切換到另一個進程。這種實現方式非常理想化,由於不同進程處於不同的地址空間,彼此之間不會干涉,這使得實現起來更為容易。

可惜的是,雖然具有以上優點,但由於進程通常都會有開銷和數量的限制,想要使用進程來並發編程顯然不夠經濟。

圖:進程的開銷( 任務管理器)

 

函數型語言可以將並發任務彼此隔離,這種專門的並發語言為處理大量並發任務提供了方便。

線程是在單一進程中創建的任務,線程與線程之間共享進程的地址空間和內存資源,Java的並發就是在順序語言的基礎上引入線程機制,通過多線程 之間的協作來實現並發。

多線程並發的好處是可以共享資源,開銷較小,然而同時也使得系統的復雜性增加。不過與程序設計的方便性,資源的負載均衡實現相比,復雜性代價也變得微不足道了。

 

    4.  線程的創建

Java中創建線程,經常用到java.lang.Thread類,如下創建一個線程:

Thread thread  = new Thread();

 

調用start()方法啟動線程

thread.start();

 

由於我們沒有繼承Thread類,重載Thread的run()方法,所以在start()之後線程沒有任何動作。

要想讓線程執行我們想要它完成的任務,還需要創建Thread的子類來重載run()方法。

 

    5.  創建Thread子類

舉個栗子

public class MyThread extends Thread {

    public void run(){

        System.out.println("ACFLOOD!");

    }

}

 

通過如下代碼來運行MyThread

MyThread myThread = new MyThread();

myThread.start();

 

    6.  實現Runnable接口

我們還可以通過實現Runnable接口來實現run()方法,你可能會問,Runnable和Thread的區別是什麼? 其實,在Java的多線程機制中,Runnable的實現就相當於一個Task,也就是我們想讓線程完成的任務。Thread的目的是用來驅動這些任務,我們想要執行Task,只需要把Runnable的實例放入Thread中。比如下面的倒計時任務LiftOff

public class LiftOff implements Runnable {

  protected int countDown = 10; //Default

  private static int taskCount = 0;

  private final int id = taskCount++;

 

  public LiftOff(){}

  public LiftOff(int countDown){

      this.countDown = countDown;

  }

 

  public String status() {

      return "#" + id  + "(" + (countDown > 0 ? countDown : "LiftOff!")+").";

  }

 

  public void run(){

      while(countDown-- > 0){

        System.out.print(status());

        Thread.yield(); //對線程調度的建議

    }

  }

}

 

 

我們可以直接調用run()方法來執行。此時程序依舊是順序執行,即只有主線程在運行,並沒有新的線程被創建。

public class MainThread {

    public static void main(String[] args){

        LiftOff launch = new LiftOff();

        laucn.run();

    }

}

 

更好的辦法是交給Thread類來調度

public class BasicThreads{

     Thread t = new Thread(new LiftOff());

     t.start();

     System.out.println("Waiting for LiftOff");       

}

 

在這個例子中,start()方法執行之後返回,之後輸出main()主線程中的waiting for liftoff,run()在另一個線程最後執行完成。

 

    7.  總結

通過本文的學習,相信讀者對並發的基本概念,並發基本的實現原理,以及java多線程對於線程的創建有了初步的了解。在本系列的後續部分將會繼續探討並發編程中的細節。

 

如果覺得本文對您有所幫助的話,就給俺點個贊吧~

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved