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
     *          interrupted status 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.
     *
     * 

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 * {@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
     * interrupted status 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).
     *
     * 

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 true if the current thread has been interrupted; * false 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 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. * * @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  true if this thread is alive;
     *          false 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.
     *
     * 

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. * *

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}. * *

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}. * *

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. * *

If none of the previous conditions hold then this thread's interrupt * status will be set.

* *

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 interrupted
     * status of the thread is unaffected by this method.
     *
     * 

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 true if this thread has been interrupted; * false otherwise. * @see #interrupted() * @revised 6.0 */ public boolean isInterrupted() { return isInterrupted(false); }

  测试线程是否已经中断,但不清除状态标识。这个和interrupted()方法区别就是不清除状态标识。

参考文献

1:《Java并发编程的艺术》

2:《Java多线程编程核心技术》