欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
你對Thread掌握多少?幸好我準備了

你好,我是田哥。

昨天,一位朋友在面試中被問(wèn)到Thread類(lèi)相關(guān)內容,個(gè)人覺(jué)得,面試官這么問(wèn),目的是考察咱們是否熟悉Thread類(lèi),是否掌握線(xiàn)程的一些常用方法和一些線(xiàn)程的基礎知識。

可能你沒(méi)遇到過(guò),但誰(shuí)也不能保證自己永遠不會(huì )遇到。

本文主要內:Thread類(lèi)的屬性和常見(jiàn)方法。

希望本文能給你帶來(lái)點(diǎn)點(diǎn)幫助。

咱們話(huà)不多說(shuō),直接開(kāi)干。

Thread(java.lang.Thread)線(xiàn)程,我們可以通過(guò)Thread類(lèi)創(chuàng )建線(xiàn)程:

Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello World!!!");
            }
        });
thread.start();

下面我們來(lái)看看Thread的核心屬性和常見(jiàn)方法:

核心屬性

1、線(xiàn)程id

private long tid;

此屬性用于保存線(xiàn)程的ID。這是一個(gè)private類(lèi)型的屬性,外部只能使用getId()方法訪(fǎng)問(wèn)線(xiàn)程的ID。方法getId(),獲取線(xiàn)程ID,線(xiàn)程ID由JVM進(jìn)行管理,在進(jìn)程內唯一。比如,1.2節的實(shí)例中,所輸出的main線(xiàn)程的ID為1。

2、線(xiàn)程名稱(chēng)

private String name;

該屬性保存一個(gè)Thread線(xiàn)程實(shí)例的名字。

方法一:public final String getName(),獲取線(xiàn)程名稱(chēng)。

方法二:public final void setName(String name),設置線(xiàn)程名稱(chēng)。

方法三:Thread(String threadName),通過(guò)此構造方法給線(xiàn)程設置一個(gè)定制化的名字。

3、線(xiàn)程優(yōu)先級

private int priority;

保存一個(gè)Thread線(xiàn)程實(shí)例的優(yōu)先級。

方法一:public final int getPriority(),獲取線(xiàn)程優(yōu)先級。

方法二:public final void setPriority(int priority),設置線(xiàn)程優(yōu)先級。

Java線(xiàn)程的最大優(yōu)先級值為10,最小值為1,默認值為5。

這三個(gè)優(yōu)先級值為三個(gè)常量值,在Thread類(lèi)中使用類(lèi)常量定義,三個(gè)類(lèi)常量如下:

public final static int MIN_PRIORITY = 1;
public final static int NORM_PRIORITY = 5;
public final static int MAX_PRIORITY = 10;

4、是否為守護線(xiàn)程

private boolean daemon=false;

該屬性保存Thread線(xiàn)程實(shí)例的守護狀態(tài),默認為false,表示是普通的用戶(hù)線(xiàn)程,而不是守護線(xiàn)程。

方法:public final void setDaemon(boolean on),將線(xiàn)程實(shí)例標記為守護線(xiàn)程或用戶(hù)線(xiàn)程,如果參數值為true,那么將線(xiàn)程實(shí)例標記為守護線(xiàn)程。

守護線(xiàn)程是在進(jìn)程運行時(shí)提供某種后臺服務(wù)的線(xiàn)程,比如垃圾回收(GC)線(xiàn)程。

5、線(xiàn)程的狀態(tài)

private int threadStatus;

該屬性以整數的形式保存線(xiàn)程的狀態(tài)。

方法:public Thread.State getState(),返回表示當前線(xiàn)程的執行狀態(tài),為新建、就緒、運行、阻塞、結束等狀態(tài)中的一種。

Thread的內部靜態(tài)枚舉類(lèi)State用于定義Java線(xiàn)程的所有狀態(tài),具體如下:

 public enum State { 
     //新建
     NEW, 
     //就緒、運行
     RUNNABLE, 
     //阻塞
     BLOCKED, 
     //等待
     WAITING, 
     //超時(shí)等待
     TIMED_WAITING, 
     //運行結束
     TERMINATED;
    } 
    public State getState() {
        // 獲取當前線(xiàn)程狀態(tài)
        return sun.misc.VM.toThreadState(threadStatus);
    }
}

在Java線(xiàn)程的狀態(tài)中,就緒狀態(tài)和運行狀態(tài)在內部用同一種狀態(tài)RUNNABLE表示。就緒狀態(tài)表示線(xiàn)程具備運行條件,正在等待獲取CPU時(shí)間片;運行狀態(tài)表示線(xiàn)程已經(jīng)獲取了CPU時(shí)間片,CPU正在執行線(xiàn)程代碼邏輯。

name線(xiàn)程名稱(chēng)

如何獲取當前線(xiàn)程名稱(chēng):


public class ThreadMethodsDemo {
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("當前線(xiàn)程名稱(chēng):"+Thread.currentThread().getName());
            }
        },"Java后端技術(shù)全棧").start();
    }
}

輸出:

當前線(xiàn)程名稱(chēng):Java后端技術(shù)全棧

上面只是舉例一種方式,還有其他方式也可以獲取。我們還是要搞清楚什么地方能設置線(xiàn)程的名稱(chēng)。

注意Thread中有個(gè)屬性name,這就是線(xiàn)程名稱(chēng)。

其實(shí)能設置線(xiàn)程名稱(chēng)的兩個(gè)地方:

第一個(gè),Thread中構造方法中能設置name都,最后都是調用這個(gè)init方法進(jìn)行name設置的。

    private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc,
                      boolean inheritThreadLocals)
 
{
        if (name == null) {
            throw new NullPointerException("name cannot be null");
        }
        //設置name的值,線(xiàn)程的名稱(chēng)
        this.name = name;
        //....省略
    }      

第二個(gè),也就是setName(String name);方法

    public final synchronized void setName(String name) {
        checkAccess();
        if (name == null) {
            throw new NullPointerException("name cannot be null");
        }
        //設置線(xiàn)程name
        this.name = name;
        if (threadStatus != 0) {
            setNativeName(name);
        }
    }

使用:

public class ThreadMethodsDemo {
    public static void main(String[] args) {
      test1();
      test2();
    }
    private static void test1(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                //輸出:當前線(xiàn)程名稱(chēng):Java后端技術(shù)全棧
                System.out.println("當前線(xiàn)程名稱(chēng):"+Thread.currentThread().getName());
            }
        },"Java后端技術(shù)全棧").start();
    }

    private static void test2(){
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                //輸出:當前線(xiàn)程名稱(chēng):老田
                System.out.println("當前線(xiàn)程名稱(chēng):"+Thread.currentThread().getName());
            }
        });
        thread.setName("老田");
        thread.start();
    }
}

建議:我們在使用的時(shí)候建議設置線(xiàn)程名稱(chēng),當出問(wèn)題的時(shí)候可以更好地辨別屬于哪個(gè)線(xiàn)程,加速問(wèn)題排除效率。

sleep線(xiàn)程睡眠

Thread.sleep(times)使當前線(xiàn)程從Running狀態(tài)放棄處理器進(jìn)入Block狀態(tài),休眠times毫秒,再返回Runnable狀態(tài)。

private static void test3(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                SimpleDateFormat format=new SimpleDateFormat("hh:mm:ss");
                //輸出系統時(shí)間的時(shí)分秒。每2秒顯示一次??赡軙?huì )出現跳秒的情況,因為阻塞1秒過(guò)后進(jìn)入runnable狀態(tài),
                //等待分配時(shí)間片進(jìn)入running狀態(tài)后還需要一點(diǎn)時(shí)間
                while(true){
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(format.format(new Date()));
                }
            }
        }).start();
}

運行:


注意:當一個(gè)線(xiàn)程處于睡眠阻塞時(shí),若被其他線(xiàn)程調用.interrupt方法中斷,則sleep方法會(huì )拋出InterruptedException異常。從上面的try--catch就能看到捕獲的是

InterruptedException中斷異常區。

看下面這段有意思的代碼,啟動(dòng)兩個(gè)子線(xiàn)程,A線(xiàn)程先睡會(huì ),B線(xiàn)程去執行,等B線(xiàn)程執行玩了后中斷A線(xiàn)程。

private static void test4() {
         /*
         * 表演者:處于睡眠阻塞的線(xiàn)程。
         * 當一個(gè)方法中的局部?jì)炔款?lèi)中需要引用該方法的其他局部變量,那么這個(gè)變量必須是final的
         */

        final Thread lin = new Thread() {
            public void run() {
                System.out.println("林:剛美完容,睡覺(jué)吧!");
                try {
                    // 當一個(gè)線(xiàn)程處于睡眠阻塞時(shí),若被其他線(xiàn)程調用interrupt()方法中斷,
                    // 則sleep()方法會(huì )拋出 InterruptedException異常
                    Thread.sleep(100000000);
                } catch (InterruptedException e) {
                    System.out.println("林:干嘛呢!都破了相了!");
                }
            }
        };
        /* 表演者:中斷睡眠阻塞的線(xiàn)程*/
        Thread huang = new Thread() {
            public void run() {
                System.out.println("黃:開(kāi)始砸墻!");
                for (int i = 0; i < 5; i++) {
                    System.out.println("黃:80!");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                    }
                }
                System.out.println("咣當!");
                System.out.println("黃:搞定!");

                // 中斷lin的睡眠阻塞
                lin.interrupt();
            }
        };
        lin.start();
        huang.start();
    }

運行結果:


setPriority線(xiàn)程優(yōu)先級

在Thread類(lèi)中有個(gè)屬性、三個(gè)常量、setPriority()方法:

//優(yōu)先級
private int priority;
public final static int MIN_PRIORITY = 1;
public final static int NORM_PRIORITY = 5;
public final static int MAX_PRIORITY = 10;

public final void setPriority(int newPriority) {
      ThreadGroup g;
      checkAccess();
      //newPriority檢查,小于1大于10都不行
      if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
          throw new IllegalArgumentException();
      }
      if((g = getThreadGroup()) != null) {
          if (newPriority > g.getMaxPriority()) {
            newPriority = g.getMaxPriority();
          }
          setPriority0(priority = newPriority);
      }
}

優(yōu)先級被劃分為1-10,1最低10最高。優(yōu)先級越高的線(xiàn)程被分配時(shí)間片的機會(huì )越多,那么被CPU執行的機會(huì )就越多。

看下面這段代碼:

private static void setPriority() {
        // 最高優(yōu)先級的線(xiàn)程
        Thread max = new Thread() {
            public void run() {
                for (int i = 0; i < 1000; i++) {
                    System.out.println("max "+Thread.currentThread().getName());
                }
            }
        };
        max.setName("max的線(xiàn)程");
        // 最低優(yōu)先級的線(xiàn)程
        Thread min = new Thread() {
            public void run() {
                for (int i = 0; i < 1000; i++) {
                    System.out.println("min "+Thread.currentThread().getName());
                }
            }
        };
        min.setName("min的線(xiàn)程");
        // 默認優(yōu)先級的線(xiàn)程
        Thread norm = new Thread() {
            public void run() {
                for (int i = 0; i < 1000; i++) {
                    System.out.println("norm "+Thread.currentThread().getName());
                }
            }
        };
        norm.setName("norm的線(xiàn)程");
        // 設置了優(yōu)先級也不能100%控制線(xiàn)程調度。
        // 只是最大程度的告知線(xiàn)程調度以更多的幾率分配時(shí)間片給線(xiàn)程優(yōu)先級高的線(xiàn)程
        max.setPriority(Thread.MAX_PRIORITY);
        min.setPriority(Thread.MIN_PRIORITY);
        // 這項設置可以省略,默認情況下就是該值
        norm.setPriority(Thread.NORM_PRIORITY);

        min.start();
        norm.start();
        max.start();
    }

運行結果就不貼了,因為每次運行的結果不一樣。因為這家伙不靠譜。

Java線(xiàn)程可以有優(yōu)先級的設定,高優(yōu)先級的線(xiàn)程比低優(yōu)先級的線(xiàn)程有更高的幾率得到執行(不完全正確,請參考下面的“線(xiàn)程優(yōu)先級的問(wèn)題“)。

  • 記住當線(xiàn)程的優(yōu)先級沒(méi)有指定時(shí),所有線(xiàn)程都攜帶普通優(yōu)先級。
  • 優(yōu)先級可以用從1到10的范圍指定。10表示最高優(yōu)先級,1表示最低優(yōu)先級,5是普通優(yōu)先級。
  • 記住優(yōu)先級最高的線(xiàn)程在執行時(shí)被給予優(yōu)先。但是不能保證線(xiàn)程在啟動(dòng)時(shí)就進(jìn)入運行狀態(tài)。
  • 與在線(xiàn)程池中等待運行機會(huì )的線(xiàn)程相比,當前正在運行的線(xiàn)程可能總是擁有更高的優(yōu)先級。
  • 由調度程序決定哪一個(gè)線(xiàn)程被執行。
  • t.setPriority()用來(lái)設定線(xiàn)程的優(yōu)先級。
  • 記住在線(xiàn)程開(kāi)始方法被調用之前,線(xiàn)程的優(yōu)先級應該被設定。
  • 你可以使用常量,如MIN_PRIORITY,MAX_PRIORITY,NORM_PRIORITY來(lái)設定優(yōu)先級。

對于線(xiàn)程優(yōu)先級,我們需要注意

  • Thread.setPriority()可能根本不做任何事情,這跟你的操作系統和虛擬機版本有關(guān)。
  • 線(xiàn)程優(yōu)先級對于不同的線(xiàn)程調度器可能有不同的含義,可能并不是你直觀(guān)的推測。特別地,優(yōu)先級并不一定是指CPU的分享。在UNIX系統,優(yōu)先級或多或少可以認為是CPU的分配,但Windows不是這樣。
  • 線(xiàn)程的優(yōu)先級通常是全局的和局部的優(yōu)先級設定的組合。Java的setPriority()方法只應用于局部的優(yōu)先級。換句話(huà)說(shuō),你不能在整個(gè)可能的范圍 內設定優(yōu)先級。(這通常是一種保護的方式,你大概不希望鼠標指針的線(xiàn)程或者處理音頻數據的線(xiàn)程被其它隨機的用戶(hù)線(xiàn)程所搶占)
  • 不同的系統有不同的線(xiàn)程優(yōu)先級的取值范圍,但是Java定義了10個(gè)級別(1-10)。這樣就有可能出現幾個(gè)線(xiàn)程在一個(gè)操作系統里有不同的優(yōu)先級,在另外一個(gè)操作系統里卻有相同的優(yōu)先級(并因此可能有意想不到的行為)。
  • 操作系統可能(并通常這么做)根據線(xiàn)程的優(yōu)先級給線(xiàn)程添加一些專(zhuān)有的行為(例如”only give a quantum boost if the priority is below X“)。這里再重復一次,優(yōu)先級的定義有部分在不同系統間有差別。
  • 大多數操作系統的線(xiàn)程調度器實(shí)際上執行的是在戰略的角度上對線(xiàn)程的優(yōu)先級做臨時(shí)操作(例如當一個(gè)線(xiàn)程接收到它所等待的一個(gè)事件或者I/O),通常操作系統知道最多,試圖手工控制優(yōu)先級可能只會(huì )干擾這個(gè)系統。
  • 你的應用程序通常不知道有哪些其它進(jìn)程運行的線(xiàn)程,所以對于整個(gè)系統來(lái)說(shuō),變更一個(gè)線(xiàn)程的優(yōu)先級所帶來(lái)的影響是難于預測的。例如你可能發(fā)現,你有一個(gè)預期 為偶爾在后臺運行的低優(yōu)先級的線(xiàn)程幾乎沒(méi)有運行,原因是一個(gè)病毒監控程序在一個(gè)稍微高一點(diǎn)的優(yōu)先級(但仍然低于普通的優(yōu)先級)上運行,并且無(wú)法預計你程序 的性能,它會(huì )根據你的客戶(hù)使用的防病毒程序不同而不同。

join線(xiàn)程協(xié)同

join()是Thread類(lèi)的一個(gè)方法,根據jdk文檔的定義,join()方法的作用,是等待這個(gè)線(xiàn)程結束,即當前線(xiàn)程等待另一個(gè)調用join()方法的線(xiàn)程執行結束后再往下執行。通常用于在main主線(xiàn)程內,等待其它調用join()方法的線(xiàn)程執行結束再繼續執行main主線(xiàn)程。

在Thread類(lèi)中有三個(gè)join方法,可能很多人也就只用過(guò)無(wú)參數的那個(gè)方法,其實(shí)Thread里是有三個(gè)方法的:


public final void join() throws InterruptedException {
  join(0);
}
public final synchronized void join(long millis, int nanos) throws InterruptedException {
  //...
  join(millis);
}
//最終的join方法實(shí)現
public final synchronized void join(long millis)throws InterruptedException {
        //當前時(shí)間戳
        long base = System.currentTimeMillis();
        long now = 0;

        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (millis == 0) {
            while (isAlive()) {
                //等待0, Object中wait方法,會(huì )釋放對象的鎖
                wait(0);
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                //等待delay, Object中wait方法,會(huì )釋放對象的鎖
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
}
   /** 
     * Tests if this thread is alive. A thread is alive if it has
     * been started and has not yet died.
     * 線(xiàn)程是否活著(zhù)
     * @return  <code>true</code> if this thread is alive;
     *          <code>false</code> otherwise.
     */

public final native boolean isAlive();//一看注釋便知道

都知道這個(gè)方法使用了同步鎖修飾,然后用到了wait方法。那就必然會(huì )想到notify和notifyAll方法。那什么時(shí)候執行喚醒這個(gè)操作呢?

下面是JVM層面的代碼:

//一個(gè)c++函數:
void JavaThread::exit(bool destroy_vm, ExitType exit_type) ;
//里面有一個(gè)賊不起眼的一行代碼
ensure_join(this);

static void ensure_join(JavaThread* thread) {
  Handle threadObj(thread, thread->threadObj());

  ObjectLocker lock(threadObj, thread);

  thread->clear_pending_exception();

  java_lang_Thread::set_thread_status(threadObj(), java_lang_Thread::TERMINATED);

  java_lang_Thread::set_thread(threadObj(), NULL);

  //同志們看到了沒(méi),別的不用看,就看這一句
  //這里就是喚醒操作  
  lock.notify_all(thread);

  thread->clear_pending_exception();
}

先來(lái)個(gè)案例演示一下:

圖片下載和圖片顯示,圖片顯示需要等待圖片下載完成后才可以顯示

public class JoinDemo {

    // 判斷照片是否下載完成
    private static boolean isFinish = false;

    public static void main(String[] args) {
        // 下載圖片的線(xiàn)程
        final Thread download = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("download:開(kāi)始下載圖片");
                for (int i = 0; i <= 100; ) {
                    i = i + 10;//為了演示
                    System.out.println("download:已完成" + i + "%");
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("download:圖片下載完畢");
                isFinish = true;
            }
        });
        download.start();

        // 用于顯示圖片的線(xiàn)程
        Thread showImg = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("show:準備顯示圖片");
                // 等待下載線(xiàn)程工作結束后,再執行下面的代碼,
                try {
                    // 此時(shí)顯示圖片的線(xiàn)程就進(jìn)入阻塞狀態(tài),等待download線(xiàn)程運行結束,
                    // 才能執行下面的代碼。注意千萬(wàn)不要在永遠也死不了的線(xiàn)程上等待
                    download.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (!isFinish) {
                    throw new RuntimeException("show:圖片還沒(méi)有下載完");
                }
                System.out.println("show:圖片顯示完成!");
            }
        });
        showImg.start();
    }
}

最后輸出:


start線(xiàn)程啟動(dòng)

都知道線(xiàn)程的啟動(dòng)是調用start()方法,繼續說(shuō)說(shuō)這個(gè)方法,在Thread中start方法:

public synchronized void start() {
    //這里private volatile int threadStatus = 0;初始化的時(shí)候就是0
    //如果這里不為0的話(huà)就拋異常
    if (threadStatus != 0)
        throw new IllegalThreadStateException();

    //把當前線(xiàn)程加入到線(xiàn)程組中
    //private ThreadGroup group;就是這么個(gè)東西
    group.add(this);

    //初始化標記位未啟動(dòng)
    boolean started = false;
    try {
        //下面
        start0();
        //標識為啟動(dòng)狀態(tài)
        started = true;
    } finally {
        try {
            //如果沒(méi)開(kāi)啟,標識為啟動(dòng)失敗
            if (!started) {
                group.threadStartFailed(this);
            }
        } catch (Throwable ignore) {

        }
    }
}
//這是虛擬機里的start0方法
private native void start0();
private Runnable target;
//建議重寫(xiě)此方法或者實(shí)現使用Runabble的run方法
//如果重寫(xiě)了Thread的run方法,那么start0方法后面會(huì )調用到子類(lèi)重寫(xiě)的run方法
//如果是實(shí)現Runnable接口中的run方法那么就會(huì )執行下面的target,run()
//否則啥都不干
@Override
public void run() {
    if (target != null) {
        //調用我們通常實(shí)現的業(yè)務(wù)代碼的run方法
        target.run();
    }
}

start0方法是虛擬機提供的,最后會(huì )調用run方法,最后執行我們在run方法里的業(yè)務(wù)代碼。

最后

關(guān)于Thread類(lèi),看起來(lái)內容不多,但是涉及到的內容卻不少,很多東西千萬(wàn)別小看,有可能下次面試你就遇到了。

另外,歡迎加入我的知識星球,現在已有200+星友了,星球內容:

簡(jiǎn)歷修改、模擬面試、無(wú)限次數技術(shù)提問(wèn)、簡(jiǎn)歷模板、專(zhuān)屬博客、Java后端學(xué)習手冊、面試小抄、每日一題、公眾號付費文免費讀、后端核心知識總結.....

還有:專(zhuān)門(mén)技術(shù)學(xué)習微信群、資料百度盤(pán)群、一對一聊技術(shù)。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Java 多線(xiàn)程編程 | 菜鳥(niǎo)教程
干貨分享|Java多線(xiàn)程面試知識點(diǎn)匯總(超詳細總結)
Java 線(xiàn)程基礎
Java多線(xiàn)程02
Java 多線(xiàn)程編程
java多線(xiàn)程
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久