線程初步認識

什麼shi線程

線程是操作系統能夠進行運算調度的最小單位,它被包含在進程之中,是進程中的實際單位

一個進程有多個線程,通過cup的切換來

爲什麼要用多線程

如果我們同時操作兩個文檔,這時候我麼用多線程 這樣有提高我們性能,
異步執行
利用多CPU 資源實現真正意義上的並行執行

線程應用場景

多線程實現文件下載
後臺任務,如向大量用戶發送郵件
異步處理信息,記錄日誌
多步驟的任務處理,多任務分割,由一個主線程分割給多個線程完成,

總的來說
合理利用cpu資源來實現線程的並行處理,來實現一個線程內的多個任務的並行執行,同時基於線程本身的異步特性實現任務處理的效率

  • 繼承 Thread 類
public class ThreadDome extends Thread {
    @Override
    public void run() {
        System.out.println("dangqi--:"+Thread.currentThread().getName());
    }
    public static void main(String[] args) {
        ThreadDome threadDome = new ThreadDome();
        threadDome.start();
    }
}
  • 實現Runable 接口
public class Runnable implements java.lang.Runnable {

    public void run() {
        System.out.println("dangqi"+Thread.currentThread().getName());
    }

    public static void main(String[] args) {
        Runnable runnable = new Runnable();
        Thread thread = new Thread(runnable);
        thread.start();

    }
}
  • 實現 Callable接口
public class Callable implements java.util.concurrent.Callable {
    public Object call() throws Exception {
        System.out.println("當前"+Thread.currentThread().getName());
        return "Callable";
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(1);
        Future submit = executorService.submit(new Callable());
        System.out.println(submit.get());
    }
}

線程生命週期

  • new 初始狀態 線程構建,但還沒有調用Start方法,
  • runnabled 運行狀態,jvm線程把操作系統中的就緒狀態和運行狀態統一稱爲行中”
  • blocked 阻塞狀態 表示線程進入等待狀態 因某種原因放棄cpu
  • waiting 等待狀態
  • time_wating 超時等待狀態,超時自動返回
  • terminated 終止狀態,表示當前線程執行完畢
    在這裏插入圖片描述

Thread.sleep(0)的意義 就
是在o的時候讓出cpu後0之後搶佔cpu,可以說是重新分配cup的一個過程

Thread.sleep(0)工作流程

  • 掛起線程修改運行狀態
  • 用sleep()提供的參數來設置一個定時器
  • 當時間結束,定時器觸發,內核收到中斷後修改線程的運行狀態

wait() 和notifyAll();,notify()

  • wait()使當前線程進入等待隊列,並釋放該線程所擁有的鎖,(而sleep()方法掛起當前線程,並不釋放該線程所擁有的鎖)等待某個條件發生變化,再由其他線程喚醒(notify)。
  • wait()方法可以有一個參數,就是等待的最長時間,若等待時長超過最長時間,該線程會從wait()中恢復執行。
  • notify()用來喚醒由wait()引起的被掛起的線程,當一個線程調用notify()時,在衆多等待同一個鎖的任務中的其中一個會被喚醒。
  • notifyAll()將喚醒所有等待當前線程所擁有的鎖的線程,
wait() 和notify實現多個線程之間的通信如生產者和消費者

生產者

public class Producer implements Runnable {
    private Queue<String> bags;
    private int size;

    public Producer(Queue<String> bags, int size) {
        this.bags = bags;
        this.size = size;
    }


    @Override
    public void run() {
        try {
            int i = 0;
            while (true) {
                i++;
                synchronized (bags) {
                    while (bags.size() == size) {
                        System.out.println("bags滿了");
                        //TODO 阻塞
                        bags.wait();
                    }
                    Thread.sleep(1000);
                    System.out.println("生產者生一個" + i);
                    bags.add("bag" + i);
                    //喚醒阻塞下的消費者
                    bags.notifyAll();
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

消費者



public class Consumer implements Runnable {

    private Queue<String> bags;
    private int size;

    public Consumer(Queue<String> bags, int size) {
        this.bags = bags;
        this.size = size;
    }

    @Override
    public void run() {
        try {
            while (true) {
                synchronized (bags) {
                    while (bags.isEmpty()) {
                        System.out.println("bags爲空了");
                        bags.wait();
                    }
                    Thread.sleep(1000);
                    String remove = bags.remove();
                    System.out.println("消費者消費" + remove);
                    //喚醒阻塞下的生產着
                    bags.notifyAll();
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

所謂的生產着和消費者
他們是雙向阻塞雙向喚醒的一個操作
他們共用一個隊列 共用一個size大小
就像生產商的產品,放到商店裏,這時候消費者吧這個產品消費了,這是一個正常的關係,但是如果商店的產品放滿了,商店告訴生產商先等一等在生產,但是如果商店的產品消費完了,商店告訴消費者等一等,這時候通過某種傳遞 ,消費者喚醒生產者,開始生產,,這時候有產品,生產商有傳遞給消費者有產品了可以消費了,就是喚醒消費者

線程中斷

  • 線程處於阻塞下(join() wait())
  • while()循環
    線程結束: 是ran方法運行結束
public class stopDemo {
    private  static  int i;

    public static void main(String[] args) {
        Thread thread  = new Thread(()->{
            while (!Thread.currentThread().isInterrupted()) 
                i++;
        });
        thread.start();
        thread.interrupt(); //中斷線程
    }
  thread.interrupt();結束線程 
Thread.currentThread().isInterrupted()

interrupted 返回一箇中斷標誌
看實例

public class StopInterr {
    private  static  int i;
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() ->{
            while (true){
                if (Thread.currentThread().isInterrupted()){
                    System.out.println("be"+Thread.currentThread().isInterrupted());
                    Thread.interrupted();
                    System.out.println("uf"+Thread.currentThread().isInterrupted());
                }
            }
        });
        thread.start();
        thread.sleep(1000);
        thread.interrupt();
    }
}
打印======
betrue
uffalse

相當於開關復位一樣。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章