Java線程入門第二篇

Java線程通訊方法

0、(why)每一個線程都有本身的棧空間,咱們要線程之間進行交流,合做雙贏。java

一、synchronized和volatile關鍵字緩存

  a) 看下面的synchronized關鍵字安全

  b) 看下面的volatile關鍵字多線程

二、等待/通知機制:一個線程A調用對象的wait()方法,另外一個線程調用線程B的notity()或者的notifyall()方法.併發

  a) 順序打印奇數偶數優化

public class ThreadPrintDemo2 {

    public static void main(String[] args) {
        final ThreadPrintDemo2 demo2 = new ThreadPrintDemo2();
        //java8新特性
        Thread t1 = new Thread(demo2 :: print1);
        Thread t2 = new Thread(demo2 :: print2);
        t1.start();
        t2.start();
    }
    public   synchronized void print2() {

        for (int i = 1; i <= 100; i +=2) {
            System.out.println(i);
            this.notify();  //通知等待中的進程
            try {
                this.wait();    //線程進入等待
                Thread.sleep(100);// 防止打印速度過快致使混亂
            } catch (InterruptedException e) {
                // NO
            }
        }
    }
    public synchronized void print1() {
        for (int i = 0; i <= 100; i += 2) {
            System.out.println(i);
            this.notify();  //通知等待中的進程
            try {
                this.wait();    //線程進入等待
                Thread.sleep(100);// 防止打印速度過快致使混亂
            } catch (InterruptedException e) {
                // NO
            }
        }
    }
}

  b) 打印連續句子this

public class ThreadPrintDemo2 {
    private char[] arr = new char[]{'a', ' ', 'b', 'c', 'd', 'e'};

    public static void main(String[] args) {
        final ThreadPrintDemo2 demo2 = new ThreadPrintDemo2();
        Thread t1 = new Thread(demo2::print1);
        Thread t2 = new Thread(demo2::print2);
        t1.start();
        t2.start();
    }
    public synchronized void print2() {

        for (int i = 1; i < arr.length; i +=2) {
            System.out.print(arr[i]);
            this.notify();
            try {
                this.wait();
                Thread.sleep(100);// 防止打印速度過快致使混亂
            } catch (InterruptedException e) {
                // NO
            }
        }
    }
    public synchronized void print1() {
        for (int i = 0; i < arr.length; i +=2) {
            System.out.print(arr[i]);
            this.notify();
            try {
                this.wait();
                Thread.sleep(100);// 防止打印速度過快致使混亂
            } catch (InterruptedException e) {
                // NO
            }
        }
    }
}

結果:a bcde
三、管道輸入輸出流:pipedreader和pipedwriter 面向字符spa

          Pipedoutputstream和pipedinputstream面向字節線程

四、使用thread.join()方法:利用線程等待特性3d

五、使用ThreadLocal線程變量

Synchronize關鍵字(重量級鎖)

一、基礎:Java中每個對象均可以做爲鎖

二、手段:確保多線程在同一時刻,只有一個線程處於方法或同步塊中

三、實現原理:JVM基於進入和退出monitor對象來實現方法同步和代碼塊同步

四、鎖優化:jdk1.6以後優化了鎖,加入了偏向鎖和輕量級鎖,鎖能夠升級但不能降級

五、使用場景:方法 代碼塊

Lock接口

在這裏插入圖片描述

一、他是一個接口

二、使用的時候須要顯式獲取鎖

三、使用方法:

Lock lock = new ReentrantLock();
lock.lock();
try {
    
}finally {
    lock.unlock();
}

四、Synchronized常常與Lock放在一塊兒比較
在這裏插入圖片描述

Volatile

一、是什麼:(what)是輕且量級的synchronize,保證共享變量的可見性(一個線程修改一個共享變量的時候,另外一個線程會知道),並他不會引發線程的上下文切換和調度。

二、使用場景:修飾變量

三、優化:在1.7中將共享變量追加了60個字節,變成64個字節。由於(硬件)目前流行的cpu的高速緩存行是64個字節,當隊列的頭尾節點不足64字節時候,處理器會將他們讀到同一個緩存行,而且鎖定緩存行。這樣會影響隊列出隊入隊效率。

ThreadLoacl類(線程變量)

爲每一個線程變量建立一個該變量的副本,避免併發訪問的線程安全問題,保證線程安全

公衆號

歡迎關注公衆號 布爾bl ,分享Java相關信息技術、生活感悟。

相關文章
相關標籤/搜索