[高併發]Java高併發編程系列開山篇--線程實現

Java是最先開始有併發的語言之一,再過去傳統多任務的模式下,人們發現很難解決一些更爲複雜的問題,這個時候咱們就有了併發.
引用html

       多線程比多任務更加有挑戰。多線程是在同一個程序內部並行執行,所以會對相同的內存空間進行併發讀寫操做。這多是在單線程程序中歷來不會遇到的問題。其中的一些錯誤也未必會在單CPU機器上出現,由於兩個線程歷來不會獲得真正的並行執行。然而,更現代的計算機伴隨着多核CPU的出現,也就意味着不一樣的線程能被不一樣的CPU核獲得真正意義的並行執行。java


       那麼,要開始Java併發之路,就要開始從java線程開始提及.
       本篇幅將是本系列博客的開山篇,也就是基礎線程的複習.git

線程簡介

線程百科

線程,有時被稱爲輕量級進程(Lightweight Process,LWP),是程序執行流的最小單元。一個標準的線程由線程ID,當前指令指針(PC),寄存器集合和堆棧組成。另外,線程是進程中的一個實體,是被系統獨立調度和分派的基本單位,線程本身不擁有系統資源,只擁有一點兒在運行中必不可少的資源,但它可與同屬一個進程的其它線程共享進程所擁有的所有資源。

線程優勢

資源利用率更好
程序設計在某些狀況下更簡單
程序響應更快github

線程代價

設計更復雜
上下文切換的開銷上升
增長資源消耗多線程

線程的實現方式

       線程咱們有不一樣的實現方式,生產環境中用到的也有所不一樣,那麼,咱們先來經過Demo看一下每種實現方式的區別.併發

經過Thread 實現的線程

public class Demo1 {
    public static void main(String args[]) {
        Thread thread = Thread.currentThread();
        System.out.println("當前線程:" + thread);

        thread.setName("hyh thread");//修改線程名稱

        System.out.println("修更名稱以後:" + thread);

        try {
            for (int a = 5; a > 0; a--) {
                System.out.println(a);

                thread.sleep(1000);
            }
        } catch (Exception e) {
            System.out.println("出現異常");
        }
    }

經過集成Runnable接口實現

Demo2.class 清單:ide

public class Demo2 implements Runnable {

    Thread t;

    //空構造函數
    Demo2() {
        t = new Thread(this, "測試線程");
        System.out.println("子線程" + t);
        t.start();
    }

    public void run() {
        try {
            for (int a = 5; a > 0; a--) {
                System.out.println("子線程" + a);
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            System.out.println("異常");
        }
        System.out.println("退出子線程");
    }
}

/**
 * 主類
 */
class ThreadDemo {
    public static void main(String args[]) {
        new Demo2();//建立一個新線程
        try {
            for (int i = 5; i > 0; i--) {
                System.out.println("主線程:" + i);
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            System.out.println("主線程異常");
        }
        //主線程退出
        System.out.println("主線程退出");

    }
}

經過集成 Thread 重寫run方法實現

public class Demo3 extends Thread {
    public Demo3() {
        //建立新線程
        super("線程Demo");
        System.out.println("子線程:" + this);
        start();
    }

    @Override
    public void run() {
        try {
            for (int a = 5; a > 0; a--) {
                System.out.println("子線程:" + a);
                Thread.sleep(500);
            }
        } catch (InterruptedException e) {
            System.out.println("子程序異常");
        }
    }

}

class MasterThread {
    public static void main(String args[]) {
        new Demo3();//建立新線程

        try {
            for (int i = 5; i > 0; i--) {
                System.out.println("主線程:" + i);
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            System.out.println("主程序異常");
        }
        System.out.println("主程序退出...");
    }
}

三個線程的實現

在平常生產中,使用線程能夠經過實現Runnable接口.下面咱們經過該方法實現簡單的三個線程Demo函數

結構: 建立一個Demo4類,另一個主類MultThreadDemo.
清單:測試

public class Demo4 implements Runnable {
 //全局變量
    String name;
    Thread thread;

    //構造器
    public Demo4(String th) {
        name = th;
        thread = new Thread(this, name);
        System.out.println("新線程" + thread);
        //開始線程
        thread.start();
    }

    //重寫run方法
    public void run() {
        try {
            for (int a = 5; a > 0; a--) {
                System.out.println(name + ":" + a);
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            System.out.println("異常");
        }
        System.out.println(name + "線程結束");
    }
}

/**
 * 測試類
 *
 * @author hyh
 */
class MultThreadDemo {

    public static void main(String[] args) {
        //建立三個線程
        Demo4 thread_1 = new Demo4("線程一");
        Demo4 thread_2 = new Demo4("線程二");
        Demo4 thread_3 = new Demo4("線程三");
        //查看狀態
        System.out.println("線程一狀態:" + thread_1.thread.isAlive());
        System.out.println("線程二狀態:" + thread_2.thread.isAlive());
        System.out.println("線程三狀態:" + thread_3.thread.isAlive());

        try {
            System.out.println("等待其餘線程結束");
            //使用join確保主線程最後運行
            thread_1.thread.join();
            thread_2.thread.join();
            thread_3.thread.join();
        } catch (InterruptedException e) {
            System.out.println("線程異常");

        }
        //查看狀態
        System.out.println("線程一:" + thread_1.thread.isAlive());
        System.out.println("線程二:" + thread_2.thread.isAlive());
        System.out.println("線程三:" + thread_3.thread.isAlive());
    }
}

到此,開山Demo完成.
本文源碼Github地址:
https://github.com/hanyahong/com-hanyahong-blog/tree/master/com-hanyahong-thread-1/src/main/java/com/hyh/threadthis

思考:進程與線程的比較

進程
資源分配的基本單位。
全部與該進程有關的資源,都被記錄在進程控制塊PCB中。
進程處理機的調度單位,擁有完整的虛擬地址空間。當進程發生調度時,不一樣的進程擁有不一樣的虛擬地址空間,而同一進程內的不一樣線程共享同一地址空間。
線程與資源分配無關,屬於某一個進程,並與其餘線程共享進程資源。
線程只由相關堆棧(系統棧或用戶棧)寄存器和線程控制表TCB組成。寄存器可被用來存儲線程內的局部變量,但不能存儲其餘線程的相關變量。
進程在多線程中,進程不是一個可執行的實體。

二者比較:
調度和切換:線程上下文切換比進程上下文切換要快得多。
通訊:進程間通訊IPC,線程間能夠直接讀寫進程數據段(如全局變量)來進行通訊——須要進程同步和互斥手段的輔助,以保證數據的一致性。
地址空間和其它資源(如打開文件):進程間相互獨立,同一進程的各線程間共享。某進程內的線程在其它進程不可見。

(本篇完)
WeChat: wixf150 原創文章,轉發請註明出處:http://www.cnblogs.com/hyhnet/p/6250264.html 訪問獨立站點,得到更好用戶體驗:http://www.hanyahong.com

相關文章
相關標籤/搜索