多線程(一)-線程基礎(chǔ)

一、線程創(chuàng)建

  • 繼承Thread類,重寫run方法;
  • 實(shí)現(xiàn)Runnable接口;
  • 實(shí)現(xiàn)Callable接口;
class MyThread extends Thread {
    @Override
    public void run() {

    }
}

class MyRunnable implements Runnable {
    @Override
    public void run() {

    }
}

class CallableImpl implements Callable<String> {
   @Override
   public String call() throws Exception {

       }
   }

public class test {
    public static void main(String[] args) {
           new MyThread().start();
           new Thread(new MyRunnable()).start();
           new Thread(new FutureTask<String>(new CallableImpl())).start();
     }
}

區(qū)別:繼承只有一次機(jī)會,Runnable實(shí)現(xiàn)不占繼承機(jī)會且可以多實(shí)現(xiàn),Callable有返回值。

二、線程生命周期

主要狀態(tài)包括:創(chuàng)建、就緒、運(yùn)行、阻塞、終止。

  • sleep()與wait():
    sleep:當(dāng)前線程睡眠;
    wait: 訪問當(dāng)前對象的線程wait,前提是當(dāng)前方法必須加鎖,如果鎖不住方法,那么調(diào)用的對象wait無從談起。
    wait的時(shí)候,鎖被釋放了,sleep的時(shí)候,鎖一直被持有。
    notify:叫醒當(dāng)前wait在我這個(gè)對象上的線程。

  • join() 在A線程中調(diào)用B線程的join,意思是兩個(gè)線程合并,A線程要等待B線程執(zhí)行完才恢復(fù)執(zhí)行。

  • yield()讓出cpu,當(dāng)前線程進(jìn)入就緒隊(duì)列等待調(diào)度。

  • getPriority()/setPriority():獲取與設(shè)置線程優(yōu)先級。

  • interrupt()中斷, 配合是否被中斷的方法一起使用,可以停止wait()方法和sleep()方法。

  • stop()非常粗暴,會強(qiáng)行把執(zhí)行到一半的線程終止,不推薦使用,貌似已經(jīng)廢棄。

三、死鎖

死鎖是兩個(gè)及以上的線程互相持有對方需要的鎖,并且都互相等待對方釋放鎖;

package com.zht.thread;

public class DeadLock implements Runnable {
    public int flag = 1;
    static Object o1 = new Object(), o2 = new Object();
    public void run() {
        if (flag == 1) {
            synchronized (o1) {
                try {
                    Thread.sleep(500);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                synchronized (o2) {
                    System.out.println("1");
                }
            }
        }
        if (flag == 0) {
            synchronized (o2) {
                try {
                    Thread.sleep(500);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                synchronized (o1) {
                    System.out.println("0");
                }
            }
        }
    }

    public static void main(String[] args) {
        DeadLock td1 = new DeadLock();
        DeadLock td2 = new DeadLock();
        td1.flag = 1;
        td2.flag = 0;
        Thread t1 = new Thread(td1);
        Thread t2 = new Thread(td2);
        t1.start();
        t2.start();
    }
}

四、生產(chǎn)者消費(fèi)者模型

這里使用wait和nofify來實(shí)現(xiàn)一個(gè)生產(chǎn)者消費(fèi)者模型

package com.zht.thread;
public class ProducerConsumer {
    public static void main(String[] args) {
        SyncStack ss = new SyncStack();
        Producer p = new Producer(ss);
        Consumer c = new Consumer(ss);
        new Thread(p).start();
        new Thread(p).start();
        new Thread(p).start();
        new Thread(c).start();
    }
}

class WoTou {
    int id;
    WoTou(int id) {
        this.id = id;
    }
    public String toString() {
        return "WoTou : " + id;
    }
}

class SyncStack {
    int index = 0;
    WoTou[] arrWT = new WoTou[6];
    public synchronized void push(WoTou wt) {
        while (index == arrWT.length) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.notifyAll();
        arrWT[index] = wt;
        index++;
    }
    public synchronized WoTou pop() {
        while (index == 0) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.notifyAll();
        index--;
        return arrWT[index];
    }
}

class Producer implements Runnable {
    SyncStack ss = null;
    Producer(SyncStack ss) {
        this.ss = ss;
    }
    public void run() {
        for (int i = 0; i < 20; i++) {
            WoTou wt = new WoTou(i);
            ss.push(wt);
            System.out.println("生產(chǎn)了:" + wt);
            try {
                Thread.sleep((int) (Math.random() * 200));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class Consumer implements Runnable {
    SyncStack ss = null;
    Consumer(SyncStack ss) {
        this.ss = ss;
    }
    public void run() {
        for (int i = 0; i < 20; i++) {
            WoTou wt = ss.pop();
            System.out.println("消費(fèi)了:" + wt);
            try {
                Thread.sleep((int) (Math.random() * 1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者。

相關(guān)閱讀更多精彩內(nèi)容

  • 林炳文Evankaka原創(chuàng)作品。轉(zhuǎn)載自http://blog.csdn.net/evankaka 本文主要講了ja...
    ccq_inori閱讀 741評論 0 4
  • ??一個(gè)任務(wù)通常就是一個(gè)程序,每個(gè)運(yùn)行中的程序就是一個(gè)進(jìn)程。當(dāng)一個(gè)程序運(yùn)行時(shí),內(nèi)部可能包含了多個(gè)順序執(zhí)行流,每個(gè)順...
    OmaiMoon閱讀 1,809評論 0 12
  • Java多線程學(xué)習(xí) [-] 一擴(kuò)展javalangThread類 二實(shí)現(xiàn)javalangRunnable接口 三T...
    影馳閱讀 3,115評論 1 18
  • 本文主要講了java中多線程的使用方法、線程同步、線程數(shù)據(jù)傳遞、線程狀態(tài)及相應(yīng)的一些線程函數(shù)用法、概述等。 首先講...
    李欣陽閱讀 2,602評論 1 15
  • 概述 本文主要講java中多線程的使用方法、線程同步、線程數(shù)據(jù)傳遞、線程狀態(tài)及相應(yīng)的線程函數(shù)用法等。首先讓我們來了...
    Tian_Peng閱讀 350評論 0 0

友情鏈接更多精彩內(nèi)容