併發編程之多線程(Java)

1、線程與進程區別

每一個正在系統上運行的程序都是一個進程。每一個進程包含一到多個線程。線程是一組指令的集合,或者是程序的特殊段,它能夠在程序裏獨立執行。也能夠把它理解爲代碼運行的上下文。因此線程基本上是輕量級的進程,它負責在單個程序裏執行多任務。一般由操做系統負責多個線程的調度和執行java

使用線程能夠把佔據時間長的程序中的任務放到後臺去處理,程序的運行速度可能加快,在一些等待的任務實現上如用戶輸入、文件讀寫和網絡收發數據等,線程就比較有用了。在這種狀況下能夠釋放一些珍貴的資源如內存佔用等等。數據庫

若是有大量的線程,會影響性能,由於操做系統須要在它們之間切換,更多的線程須要更多的內存空間,線程的停止須要考慮其對程序運行的影響。一般塊模型數據是在多個線程間共享的,須要防止線程死鎖狀況的發生。api

總結:進程是全部線程的集合,每個線程是進程中的一條執行路徑。網絡

2、爲何要使用多線程?

多線程提升程序執行效率。
如: 迅雷多線程下載、數據庫鏈接池、分批發送短信等。多線程

3、多線程建立方式

一、第一種繼承Thread類 重寫run方法

/**
 * 
 * @classDesc: 功能描述:(建立多線程例子-Thread類 重寫run方法)
 */
class CreateThread extends Thread {
    // run方法中編寫 多線程須要執行的代碼
    public void run() {
        for (inti = 0; i< 10; i++) {
            System.out.println("i:" + i);
        }
    }
}
public class ThreadDemo {

    public static void main(String[] args) {
        System.out.println("-----多線程建立開始-----");
        // 1.建立一個線程
        CreateThread createThread = new CreateThread();
        // 2.開始執行線程 注意 開啓線程不是調用run方法,而是start方法
        System.out.println("-----多線程建立啓動-----");
        createThread.start();
        System.out.println("-----多線程建立結束-----");
    }

}

二、第二種實現Runnable接口,重寫run方法

/**
 * 
 * @classDesc: 功能描述:(建立多線程例子-Thread類 重寫run方法)
 */
class CreateRunnable implements Runnable {

    @Override
    publicvoid run() {
        for (inti = 0; i< 10; i++) {
            System.out.println("i:" + i);
        }
    }

}

/**
 * 
 * @classDesc: 功能描述:(實現Runnable接口,重寫run方法)
 */
public class ThreadDemo2 {
    public static void main(String[] args) {
        System.out.println("-----多線程建立開始-----");
        // 1.建立一個線程
        CreateRunnable createThread = new CreateRunnable();
        // 2.開始執行線程 注意 開啓線程不是調用run方法,而是start方法
        System.out.println("-----多線程建立啓動-----");
        Thread thread = new Thread(createThread);
        thread.start();
        System.out.println("-----多線程建立結束-----");
    }
}

三、第三種使用匿名內部類方式

public class ThreadDemo3 {
    public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            public void run() {
                for (int i = 0; i< 10; i++) {
                    System.out.println("i:" + i);
                }
            }
        });
         thread.start();
    }
}

4、經常使用APi

使用繼承Thread類仍是使用實現Runnable接口好?

使用實現實現Runnable接口好,緣由實現了接口還能夠繼續繼承,繼承了類不能再繼承。ide

獲取線程對象以及名稱

經常使用線程api方法函數

start() 啓動線程性能

currentThread() 獲取當前線程對象操作系統

getID() 獲取當前線程ID Thread-編號  該編號從0開始線程

getName() 獲取當前線程名稱

sleep(long mill) 休眠線程

Stop() 中止線程,

經常使用線程構造函數

Thread() 分配一個新的 Thread 對象

Thread(String name) 分配一個新的 Thread對象,具備指定的 name正如其名。

Thread(Runable r) 分配一個新的 Thread對象

Thread(Runable r, String name) 分配一個新的 Thread對象

5、守護線程

Java中有兩種線程,一種是用戶線程,另外一種是守護線程。

用戶線程是指用戶自定義建立的線程,主線程中止,用戶線程不會中止

守護線程當進程不存在或主線程中止,守護線程也會被中止。

使用setDaemon(true)方法設置爲守護線程

thread.setDaemon(true)
# 6、join()方法做用

當在主線程當中執行到t1.join()方法時,就認爲主線程應該把執行權讓給t1

Thread t1 = new Thread(new Runnable() {

           @Override
           public void run() {
               for (int i = 0; i < 10; i++) {
                   try {
                       Thread.sleep(10);
                   } catch (Exception e) {

                   }
                   System.out.println(Thread.currentThread().getName() + "i:" + i);
               }
           }
       });
       t1.start();
       // 當在主線程當中執行到t1.join()方法時,就認爲主線程應該把執行權讓給t1
       t1.join();
       for (int i = 0; i < 10; i++) {
           try {
               Thread.sleep(10);
           } catch (Exception e) {

           }
           System.out.println("main" + "i:" + i);
       }

# 7、優先級
現代操做系統基本採用時分的形式調度運行的線程,線程分配獲得的時間片的多少決定了線程使用處理器資源的多少,也對應了線程優先級這個概念。在JAVA線程中,經過一個int priority來控制優先級,範圍爲1-10,其中10最高,默認值爲5。下面是源碼(基於1.8)中關於priority的一些量和方法。

class PrioritytThread implements Runnable {

    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().toString() + "---i:" + i);
        }
    }
}

/**
 * 
 * @classDesc: 
 */
public class ThreadDemo4 {

    public static void main(String[] args) {
        PrioritytThread prioritytThread = new PrioritytThread();
        Thread t1 = new Thread(prioritytThread);
        Thread t2 = new Thread(prioritytThread);
        t1.start();
        // 注意設置了優先級, 不表明每次都必定會被執行。 只是CPU調度會有限分配
        t1.setPriority(10);
        t2.start();
        
    }

}

8、Yield方法

Thread.yield()方法的做用:暫停當前正在執行的線程,並執行其餘線程。(可能沒有效果)yield()讓當前正在運行的線程回到可運行狀態,以容許具備相同優先級的其餘線程得到運行的機會。所以,使用yield()的目的是讓具備相同優先級的線程之間可以適當的輪換執行。可是,實際中沒法保證yield()達到讓步的目的,由於,讓步的線程可能被線程調度程序再次選中。結論:大多數狀況下,yield()將致使線程從運行狀態轉到可運行狀態,但有可能沒有效果。

相關文章
相關標籤/搜索