1. 程式人生 > >JDK8原始碼閱讀筆記--------java.lang.Thread

JDK8原始碼閱讀筆記--------java.lang.Thread

A thread is a thread of execution in a program. The Java Virtual Machine allows an application to have multiple threads of execution running concurrently.
Every thread has a priority. Threads with higher priority are executed in preference to threads with lower priority. Each thread may or may not also be marked as a daemon. When code running in some thread creates a new Thread object, the new thread has its priority initially set equal to the priority of the creating thread, and is a daemon thread if and only if the creating thread is a daemon.
When a Java Virtual Machine starts up, there is usually a single non-daemon thread (which typically calls the method named main of some designated class). The Java Virtual Machine continues to execute threads until either of the following occurs:

*The exit method of class Runtime has been called and the security manager has permitted the exit operation to take place.
*All threads that are not daemon threads have died, either by returning from the call to the run method or by throwing an exception that propagates beyond the run method.

There are two ways to create a new thread of execution. One is to declare a class to be a subclass of Thread. This subclass should override the run method of class Thread. An instance of the subclass can then be allocated and started. For example, a thread that computes primes larger than a stated value could be written as follows:

class PrimeThread extends Thread {
           long minPrime;
           PrimeThread(long minPrime) {
               this.minPrime = minPrime;
           }
  
           public void run() {
               // compute primes larger than minPrime
                . . .
           }
       }

The following code would then create a thread and start it running:
       PrimeThread p = new PrimeThread(143);
       p.start();
The other way to create a thread is to declare a class that implements the Runnable interface. That class then implements the run method. An instance of the class can then be allocated, passed as an argument when creating Thread, and started. The same example in this other style looks like the following:

The other way to create a thread is to declare a class that implements the Runnable interface. That class then implements the run method. An instance of the class can then be allocated, passed as an argument when creating Thread, and started. The same example in this other style looks like the following:

 class PrimeRun implements Runnable {
           long minPrime;
           PrimeRun(long minPrime) {
               this.minPrime = minPrime;
           }
  
           public void run() {
               // compute primes larger than minPrime
                . . .
           }
       }

The following code would then create a thread and start it running:
       PrimeRun p = new PrimeRun(143);
       new Thread(p).start();
   
Every thread has a name for identification purposes. More than one thread may have the same name. If a name is not specified when a thread is created, a new name is generated for it.
Unless otherwise noted, passing a null argument to a constructor or method in this class will cause a NullPointerException to be thrown.

 大意為:

執行緒是程式中的執行執行緒。Java虛擬機器允許應用程式同時執行多個執行執行緒。每個執行緒都有優先順序。優先順序較高的執行緒優先於優先順序較低的執行緒執行。每個執行緒可能被標記為守護程序,也可能不被標記為守護程序。當在某個執行緒中執行的程式碼建立一個新的執行緒物件時,新執行緒的優先順序最初設定為與建立執行緒的優先順序相等,並且當且僅當建立執行緒是一個守護執行緒時,它就是一個守護執行緒。以及建立執行緒的兩種方式。為了便於識別,每個執行緒都有一個名稱。多個執行緒可能具有相同的名稱。如果在建立執行緒時沒有指定名稱,則會為其生成一個新名稱。

Thread實現Runnable介面

1.執行緒優先順序

從1-10一次增大,預設5:

/**
  * The minimum priority that a thread can have.
  */
 public final static int MIN_PRIORITY = 1;

/**
  * The default priority that is assigned to a thread.
  */
 public final static int NORM_PRIORITY = 5;

 /**
  * The maximum priority that a thread can have.
  */
 public final static int MAX_PRIORITY = 10;

2.靜態方法 currentThread()

Returns a reference to the currently executing thread object.

Thread.currentThread();獲得當前執行緒物件。

3.靜態方法 yield()

A hint to the scheduler that the current thread is willing to yield its current use of a processor. The scheduler is free to ignore this hint.
Yield is a heuristic attempt to improve relative progression between threads that would otherwise over-utilise a CPU. Its use should be combined with detailed profiling and benchmarking to ensure that it actually has the desired effect.
It is rarely appropriate to use this method. It may be useful for debugging or testing purposes, where it may help to reproduce bugs due to race conditions. It may also be useful when designing concurrency control constructs such as the ones in the java.util.concurrent.locks package.

給排程器的提示,即當前執行緒願意放棄當前對處理器的使用。排程程式可以忽略這個提示。

Yield是一個啟發式的嘗試,旨在改進執行緒之間的相對程序,否則會過度使用CPU。它的使用應該與詳細的分析和基準測試相結合,以確保它確實具有預期的效果。

很少使用這種方法。它可能對除錯或測試很有用,因為它可能會因為競爭條件而幫助重現bug。在設計併發控制結構(比如java.util.concurrent中的結構)時,它可能也很有用。

4.靜態:sleep(long millis)、sleep(long millis, int nanos)

Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers. The thread does not lose ownership of any monitors.

執行緒睡眠指定毫秒數,但是不放棄監視器的所有權。

5.有(無)參構造方法:

執行緒名:預設Thread-int,可以指定

target:比如某類(ARunnable)實現runnable介面,則可以new Thread(new ARunnable()).start。

stackSize:設定新執行緒堆疊記憶體,0表示忽略。

6.被synchronized修飾 start():

Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.
The result is that two threads are running concurrently: the current thread (which returns from the call to the start method) and the other thread (which executes its run method).
It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution.

大意是:是當前執行緒開始執行。虛擬機器呼叫執行緒的run方法。結果是兩個執行緒同時執行:當前執行緒(從呼叫開始方法返回)和另一個執行緒(執行其執行方法)。多次啟動執行緒是不合法的。特別是,執行緒一旦完成執行,可能就不會重新啟動。

7.run():

If this thread was constructed using a separate Runnable run object, then that Runnable object's run method is called; otherwise, this method does nothing and returns.
Subclasses of Thread should override this method.

如果這個執行緒是使用一個單獨的Runnable run物件構造的,則呼叫該Runnable物件的run方法;否則,此方法不執行任何操作並返回。執行緒的子類應該重寫這個方法。

8.interrupt()

中斷執行緒。

9.isInterrupted()

Tests whether this thread has been interrupted. The interrupted status of the thread is unaffected by this method.

判斷執行緒是否被中斷了。

 

public static void main(final String[] args) {

        Thread thread = new Thread();
        //開啟執行緒
        thread.start();
        //中斷執行緒
        thread.interrupt();
        //測試是否中斷
        boolean interrupted = thread.isInterrupted();
        System.out.println(interrupted);//true
    }

 

10.isAlive()

Tests if this thread is alive. A thread is alive if it has been started and has not yet died.

11.setPriority(int newPriority)、getPriority()

設定(獲取)執行緒的優先順序。

12.setName(String name)、getName()

設定、獲取執行緒名。

13.被synchronized修飾join(long millis),join()--實際是join(0)

Waits at most millis milliseconds for this thread to die. A timeout of 0 means to wait forever.
This implementation uses a loop of this.wait calls conditioned on this.isAlive. As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.

等待執行緒死亡的時間最多為千分之一毫秒。超時為0意味著永遠等待。這個實現使用這個迴圈。基於此條件的等待呼叫。當執行緒終止此操作時。呼叫notifyAll方法。建議應用程式不要線上程例項上使用wait、notify或notifyAll。

原理是join方法內部呼叫object類的wait方法。

14.setDaemon(boolean on)

Marks this thread as either a daemon thread or a user thread. The Java Virtual Machine exits when the only threads running are all daemon threads.
This method must be invoked before the thread is started.

將該執行緒標記為守護程序執行緒或使用者執行緒。當惟一執行的執行緒都是守護程序執行緒時,Java虛擬機器將退出。必須在啟動執行緒之前呼叫此方法。

如果該執行緒isAlive(),不能設定為守護執行緒。

15.getContextClassLoader()

Returns the context ClassLoader for this Thread. The context ClassLoader is provided by the creator of the thread for use by code running in this thread when loading classes and resources. If not set, the default is the ClassLoader context of the parent Thread. The context ClassLoader of the primordial thread is typically set to the class loader used to load the application.
If a security manager is present, and the invoker's class loader is not null and is not the same as or an ancestor of the context class loader, then this method invokes the security manager's checkPermission method with a RuntimePermission("getClassLoader") permission to verify that retrieval of the context class loader is permitted.

獲取該執行緒的上下文類載入器。下文類載入器是由執行緒的建立者提供的,以便在載入類和資源時由該執行緒中執行的程式碼使用。如果不設定,預設是父執行緒的類載入器。

16.setContextClassLoader(ClassLoader cl)

Sets the context ClassLoader for this Thread. The context ClassLoader can be set when a thread is created, and allows the creator of the thread to provide the appropriate class loader, through getContextClassLoader, to code running in the thread when loading classes and resources.

17.狀態列舉類State

包含new,runnable,blocked,waiting,timed_waiting,terminated.