java多線程2:Thread中的方法

靜態方法:

Thread類中的靜態方法表示操作的線程是"正在執行靜態方法所在的代碼塊的線程"。

爲什麼Thread類中要有靜態方法,這樣就能對CPU當前正在運行的線程進行操作。下面來看一下Thread類中的靜態方法:

1:currentThread 


/** * Returns a reference to the currently executing thread object. * * @return the currently executing thread. */ public static native Thread currentThread();

 currentThread()方法返回的是對當前正在執行線程對象的引用。

/**
 * 測試Thread.currentThread():返回代碼段正在被哪個線程調用的信息
 * this 始終表示線程實例本身
 *
 * @author yuxiaoyu
 */
public class Mythread4 extends Thread {
  static {
      System.out.println("Mythread4靜態塊的打印:Thread.currentThread().getName()=" + Thread.currentThread().getName());
  }
    public Mythread4() {
        System.out.println("Mythread4構造方法:Thread.currentThread().getName()=" + Thread.currentThread().getName());
        System.out.println("Mythread4構造方法:this.getName()=" + this.getName());
    }

    public void run() {
        System.out.println("run 方法:Thread.currentThread().getName()=" + Thread.currentThread().getName());
        System.out.println("run 方法:this.getName()=" + this.getName());
    }

}
@Test
	public void test4() {
		Mythread4 a = new Mythread4();
		a.start();
	}

  執行結果:

Mythread4靜態塊的打印:Thread.currentThread().getName()=main
Mythread4構造方法:Thread.currentThread().getName()=main
Mythread4構造方法:this.getName()=Thread-0
run 方法:Thread.currentThread().getName()=Thread-0
run 方法:this.getName()=Thread-0

  這個結果說明,線程類的構造方法、靜態塊是被main線程調用的,而線程類的run()方法纔是應用線程自己調用的,this 始終表示線程實例本身。

 

2:sleep

/**
     * 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.
     *
     * @param  millis
     *         the length of time to sleep in milliseconds
     *
     * @throws  IllegalArgumentException
     *          if the value of {@code millis} is negative
     *
     * @throws  InterruptedException
     *          if any thread has interrupted the current thread. The
     *          <i>interrupted status</i> of the current thread is
     *          cleared when this exception is thrown.
     */
    public static native void sleep(long millis) throws InterruptedException; 

 該方法是讓正在執行的線路休眠指定毫秒,注意API的註釋中“The thread does not lose ownership of any monitors.”表示線程不會失去任何監視器的所有權。

 簡單說就是sleep代碼上下文如果被加鎖了,那麼在休眠的時間內,鎖依然在,但是CPU資源會讓出給其他線程。 

 

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.
     *
     * <p> 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.
     *
     * <p> 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
     * {@link java.util.concurrent.locks} package.
     */
    public static native void yield();

  該方法表示給調度程序的一個提示:當前線程願意讓出它當前對處理器的使用。調度程序可以自由地忽略這個提示。

public class Mythread5 extends Thread {

    public void run() {
        long beginTime = System.currentTimeMillis();
        int count = 0;
        for (int i = 0; i < 50000000; i++)
        {
            Thread.yield();
            count = count + i + 1;
        }
        long endTime = System.currentTimeMillis();
        System.out.println("用時:" + (endTime - beginTime) + "毫秒!");
    }
}

  第一次運行結果:用時:34872毫秒!

  第二次運行結果:用時:33738毫秒!

如果將 Thread.yield(); 註釋掉的話, 運行結果:用時:48毫秒!。

看到,每次執行的用時都不一樣,證明了yield()方法放棄CPU的時間並不確定,而且yield方法將CPU資源讓給其他資源導致變慢。

 

4:interrupted()

/**
     * Tests whether the current thread has been interrupted.  The
     * <i>interrupted status</i> of the thread is cleared by this method.  In
     * other words, if this method were to be called twice in succession, the
     * second call would return false (unless the current thread were
     * interrupted again, after the first call had cleared its interrupted
     * status and before the second call had examined it).
     *
     * <p>A thread interruption ignored because a thread was not alive
     * at the time of the interrupt will be reflected by this method
     * returning false.
     *
     * @return  <code>true</code> if the current thread has been interrupted;
     *          <code>false</code> otherwise.
     * @see #isInterrupted()
     * @revised 6.0
     */
    public static boolean interrupted() {
        return currentThread().isInterrupted(true);
    }
/**
     * Tests if some Thread has been interrupted.  The interrupted state
     * is reset or not based on the value of ClearInterrupted that is
     * passed.
     */
    private native boolean isInterrupted(boolean ClearInterrupted);

  

  測試當前線程是否已經中斷,並清除線程的中斷狀態。

 

實例方法

1:start

/**
     * Causes this thread to begin execution; the Java Virtual Machine
     * calls the <code>run</code> method of this thread.
     * <p>
     * The result is that two threads are running concurrently: the
     * current thread (which returns from the call to the
     * <code>start</code> method) and the other thread (which executes its
     * <code>run</code> method).
     * <p>
     * It is never legal to start a thread more than once.
     * In particular, a thread may not be restarted once it has completed
     * execution.
     *
     * @exception  IllegalThreadStateException  if the thread was already
     *               started.
     * @see        #run()
     * @see        #stop()
     */
    public synchronized void start() {
        /**
         * This method is not invoked for the main method thread or "system"
         * group threads created/set up by the VM. Any new functionality added
         * to this method in the future may have to also be added to the VM.
         *
         * A zero status value corresponds to state "NEW".
         */
        if (threadStatus != 0)
            throw new IllegalThreadStateException();

        /* Notify the group that this thread is about to be started
         * so that it can be added to the group's list of threads
         * and the group's unstarted count can be decremented. */
        group.add(this);

        boolean started = false;
        try {
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                /* do nothing. If start0 threw a Throwable then
                  it will be passed up the call stack */
            }
        }
    }

  

此方法告訴線程執行器,這個線程可以執行了。

2:isAlive

/**
     * Tests if this thread is alive. A thread is alive if it has
     * been started and has not yet died.
     *
     * @return  <code>true</code> if this thread is alive;
     *          <code>false</code> otherwise.
     */
    public final native boolean isAlive();

  判斷當前的線程是否處於活動狀態,活動狀態就是線程已經啓動且尚未終止。線程處於正在運行或準備開始運行的狀態,就認爲線程是“存活”的。

public class Mythread7_2 extends Thread {

    public Mythread7_2() {
        System.out.println("Mythread7_2---begin");

        System.out.println("Thread.currentThread().getName()=" + Thread.currentThread().getName());
        System.out.println("Thread.currentThread().isAlive()=" + Thread.currentThread().isAlive());

        System.out.println("this.getName()=" + this.getName());
        System.out.println("this.isAlive()=" + this.isAlive());

        System.out.println("Mythread7_2---end");
    }

    @Override
    public void run() {
        System.out.println("run---begin");

        System.out.println("Thread.currentThread().getName()=" + Thread.currentThread().getName());
        System.out.println("Thread.currentThread().isAlive()=" + Thread.currentThread().isAlive());

        System.out.println("this.getName()=" + this.getName());
        System.out.println("this.isAlive()=" + this.isAlive());

        System.out.println("run---end");
    }

}
@Test
	public void test7_2() {
		Mythread7_2 c = new Mythread7_2();
		System.out.println("main begin t1 isAlive=" + c.isAlive());
		c.setName("A");
		c.start();
		System.out.println("main end t1 isAlive=" + c.isAlive());
	}

  執行結果:

Mythread7_2---begin
Thread.currentThread().getName()=main
Thread.currentThread().isAlive()=true
this.getName()=Thread-0
this.isAlive()=false
Mythread7_2---end
main begin t1 isAlive=false
run---begin
Thread.currentThread().getName()=A
Thread.currentThread().isAlive()=true
this.getName()=A
this.isAlive()=true
run---end
main end t1 isAlive=false

  可以看出:只有在當前實例對象調用了start方法時,this.isAlive()才返回true。

3:interrupt

/**
     * Interrupts this thread.
     *
     * <p> Unless the current thread is interrupting itself, which is
     * always permitted, the {@link #checkAccess() checkAccess} method
     * of this thread is invoked, which may cause a {@link
     * SecurityException} to be thrown.
     *
     * <p> If this thread is blocked in an invocation of the {@link
     * Object#wait() wait()}, {@link Object#wait(long) wait(long)}, or {@link
     * Object#wait(long, int) wait(long, int)} methods of the {@link Object}
     * class, or of the {@link #join()}, {@link #join(long)}, {@link
     * #join(long, int)}, {@link #sleep(long)}, or {@link #sleep(long, int)},
     * methods of this class, then its interrupt status will be cleared and it
     * will receive an {@link InterruptedException}.
     *
     * <p> If this thread is blocked in an I/O operation upon an {@link
     * java.nio.channels.InterruptibleChannel InterruptibleChannel}
     * then the channel will be closed, the thread's interrupt
     * status will be set, and the thread will receive a {@link
     * java.nio.channels.ClosedByInterruptException}.
     *
     * <p> If this thread is blocked in a {@link java.nio.channels.Selector}
     * then the thread's interrupt status will be set and it will return
     * immediately from the selection operation, possibly with a non-zero
     * value, just as if the selector's {@link
     * java.nio.channels.Selector#wakeup wakeup} method were invoked.
     *
     * <p> If none of the previous conditions hold then this thread's interrupt
     * status will be set. </p>
     *
     * <p> Interrupting a thread that is not alive need not have any effect.
     *
     * @throws  SecurityException
     *          if the current thread cannot modify this thread
     *
     * @revised 6.0
     * @spec JSR-51
     */
    public void interrupt() {
        if (this != Thread.currentThread())
            checkAccess();

        synchronized (blockerLock) {
            Interruptible b = blocker;
            if (b != null) {
                interrupt0();           // Just to set the interrupt flag
                b.interrupt(this);
                return;
            }
        }
        interrupt0();
    }

  interrupt並不會立刻停止線程,interrupt0的作用僅僅是爲當前線程打一箇中斷的標誌。

4:isInterrupted

/**
     * Tests whether this thread has been interrupted.  The <i>interrupted
     * status</i> of the thread is unaffected by this method.
     *
     * <p>A thread interruption ignored because a thread was not alive
     * at the time of the interrupt will be reflected by this method
     * returning false.
     *
     * @return  <code>true</code> if this thread has been interrupted;
     *          <code>false</code> otherwise.
     * @see     #interrupted()
     * @revised 6.0
     */
    public boolean isInterrupted() {
        return isInterrupted(false);
    }

  測試線程是否已經中斷,但不清除狀態標識。這個和interrupted()方法區別就是不清除狀態標識。

 

參考文獻

1:《Java併發編程的藝術》

2:《Java多線程編程核心技術》

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