您好,欢迎来到二三娱乐。
搜索
您的当前位置:首页Thread (core java)

Thread (core java)

来源:二三娱乐

创建线程

建议不要通过构建Thread子类对象,并调用start方法。应该从运行机制上减少需要并行运行的任务数量。如果有很多任务,要为每个任务创建一个独立的线程付出的代价太大,可以使用线程池来解决这个问题。(参考14.9)

java.lang.Thread

  1. Thread(Runnable target) 构造一个新线程用于调用给定target的run方法。
  2. void start() 启动此线程,将引发调用run()方法,这个方法会立即返回,并且新线程将并行运行。
  3. void run() 调用关联Runnable的run方法。

java.lang.Runnable

  1. void run() 必须覆盖这个方法,并在这个方法中提供所需要执行的任务指令。

中断线程

早期java使用stop()方法可以强制线程中止,现在已经被弃用;
interrupt() 方法可以用来请求中止线程。但是如果线程被阻塞,就无法检测中断状态。这是产生InterruptedException异常的地方,当在一个被阻塞的线程(调用sleep或wait)上调用interrupt方法时,阻塞调用将会被InterruptedException异常中断,这里指会进入catch代码块执行(存在不能被中断的阻塞I/O调用,应该考虑选择可中断的调用。细节参考卷二 第一章和第三章)
java.lang.Thread

  1. void interrupt() 向线程发送中断请求,线程的中断状态将被设置为true.
    如果目前线程被一个sleep调用阻塞,那么InterruptedException异常被抛出,此外中断状态将被清除
  2. static boolean interrupted() 测试正在执行这一方法的线程是否被中断,注意这是一个静态方法,调用会产生副作用,它将当前线程的中断状态重置为false.(线程的中断状态被清除)
  3. boolean isInterrupted() 测试线程是否终止,不像静态的中断方法,这一调用不改变线程的中断状态。
  4. static Thread currentThread() 返回代表当前执行线程的Thread对象。
  5. static void sleep(long millis) 休眠给定的毫秒数

void interrupt() 中断此线程。(谷歌翻译)
线程用一个变量来标志中断状态,private volatile Interruptible blocker;
除非当前线程正在中断自身(始终允许),否则将调用此线程的checkAccess方法,这可能导致抛出SecurityException。
如果在调用Object类的wait(),wait(long)或wait(long,int)方法或者join(),join(long),join(long,int)的方法中阻塞了这个线程,sleep(long)或sleep(long,int),这个类的方法,然后它的中断状态将被清除,它将收到InterruptedException。
如果此线程在可中断通道上的I / O操作中被阻塞,则通道将被关闭,线程的中断状态将被设置,并且线程将收到ClosedByInterruptException。
如果此线程在Selector中被阻塞,则线程的中断状态将被设置,并且它将立即从选择操作返回,可能具有非零值,就像调用选择器的唤醒方法一样。
如果以前的条件都不成立,则将设置该线程的中断状态。
中断不活动的线程不会产生任何影响。

public class TestRun implements Runnable {
    private boolean flag = true;

    @Override
    public void run() {
        try {
            while (!Thread.currentThread().isInterrupted() && flag) {
                // do more work
                Thread.currentThread().sleep(1000);
            }
        }
        catch (InterruptedException e) {
            // thread was interrupted during sleep or wait
            
        }
        finally {
            //cleanup,if required
        }
        //exiting the run method terminates the thread
    }
    
    void mySubTask() {
        try {
            Thread.currentThread().sleep(1000);
        }
        catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
    
    void mySubTask2() throws InterruptedException {
        Thread.currentThread().sleep(1000);
    }
}

线程状态

  1. 新建 New
    new Thread(r)/new MyThread()
  2. 可运行 Runnable
    thread.start()
    (抢占式调度系统;协作式调度系统中,一个线程只有在调用yield方法或者被阻塞或等待时,线程才会失去控制权)
    任何时刻,一个可运行的线程可能正在运行,也可能没有运行
  3. 被阻塞 Blocked
    一个线程试图获取一个内部对象锁,而该锁被其它对象持有,则线程进入阻塞状态。
  4. 等待 Waiting/ 计时等待 Timed waiting
    Thread.sleep
    Object.wait
    Thread.join
    Lock.tryLock
    Condition.await
  5. 被中止 Terminated
    因为run方法正常退出而自然死亡
    因为一个没有捕获的异常中止了run方法而意外死亡
    stop方法已过时,不要在代码中使用
  6. 相关的API
    java.lang.Thread

6.1void join():等待中止指定的线程即等待指定的线程终止后再继续当前线程
6.2void join(long millis):等待指定的线程死亡,或者经过指定的毫秒数
6.3Thread.State getState():获取线程的状态
6.4void stop():停止线程,已过时
6.5void suspend:暂停线程执行,已过时
6.6void resume:调用suspend之后调用,已过时

线程属性

  1. 优先级
    高优先级只代表线程优先获取时间片的可能性比较大,不是必然
  2. API
    java.lang.Thread

2.1void setPriority(int newPriority):设置优先级,必须在Thread.MIN_PRIORITY与Thread.MAX_PRIORITY之间,一般使用Thread.NORM_PRIORITY优先级。
2.2static int MIN_PRIORITY:线程最小优先级1.
2.3static int MAX_PRIORITY:线程最大优先级10.
2.4static int NORM_PRIORITY:线程默认优先级5.
2.5static void yield():导致当前执行线程处于让步状态,如果有其他可运行的线程具有至少与此线程同样高的优先级,那么这些线程接下来会被调度。注意,这是一个静态方法。

3.守护线程/API
3.守护线程优先级很低,当同一应用程序中没有其他线程在运行的时候,守护线程才运行。当守护线程是程序中唯一运行的线程时,守护线程执行结束后,JVM也就结束了这个程序。
3.2守护线程的作用:通常作为同一程序中普通线程的服务提供者,它们通常是无限循环的,以等待服务请求或者执行线程的任务。此外我们不太可能知道守护线程什么时候能够获取CPU时钟,并且没有其它线程运行的时候,守护线程随时可能结束。一个典型的守护线程是Java的垃圾回收器。
java.lang.Thread

3.3void setDaemon(boolean isDaemon):标识该线程为守护线程或用户线程。这一方法必须在线程启动之前调用

4未捕获异常处理器
4.1未捕获异常处理器介绍
线程的run方法不能抛出任何被检测的异常,但是,不被检测的异常会导致线程终止。在这种情况下,线程就死亡了。就作线程死亡之前,异
常被传递到一个用于未捕获异常的处理器。
该处理器必须属于一个实现Thread.UncaughtExceptionHandler接口的类。
这个接口只有一个方法。
void uncauqhtException(Thread t, Throwable e)
可以用 setUncaughtExceptionHandler方法为任何线程安装一个处理器。也可以用 Thread类的静态方法setDefaultUncaughtExceptionHandlcr为所有线程安装一个默认的处理器。如果不安装默认的处理器,默认的处理器为空。但是,如果没有设置UncaughtExceptionHandler,那么默认将会把异常栈信息输出到System.err,此时的处理器就足该线程的ThreadGroup对象

线程组是一个可以统一管理的线程集合。默认情况下,创建的所有线程属于相同的线程组,但是,也可能会建立其他的组。现在引入了更好的特性用于线程集合的操作,所以建议不要在自己的程序中使用线程组。
ThreadGroup 类实现 Thread.UncaughtException 接口。它的uncaughtException方法如下:

 /**
     * Called by the Java Virtual Machine when a thread in this
     * thread group stops because of an uncaught exception, and the thread
     * does not have a specific {@link Thread.UncaughtExceptionHandler}
     * installed.
     * <p>
     * The <code>uncaughtException</code> method of
     * <code>ThreadGroup</code> does the following:
     * <ul>
     * <li>If this thread group has a parent thread group, the
     *     <code>uncaughtException</code> method of that parent is called
     *     with the same two arguments.
     * <li>Otherwise, this method checks to see if there is a
     *     {@linkplain Thread#getDefaultUncaughtExceptionHandler default
     *     uncaught exception handler} installed, and if so, its
     *     <code>uncaughtException</code> method is called with the same
     *     two arguments.
     * <li>Otherwise, this method determines if the <code>Throwable</code>
     *     argument is an instance of {@link ThreadDeath}. If so, nothing
     *     special is done. Otherwise, a message containing the
     *     thread's name, as returned from the thread's {@link
     *     Thread#getName getName} method, and a stack backtrace,
     *     using the <code>Throwable</code>'s {@link
     *     Throwable#printStackTrace printStackTrace} method, is
     *     printed to the {@linkplain System#err standard error stream}.
     * </ul>
     * <p>
     * Applications can override this method in subclasses of
     * <code>ThreadGroup</code> to provide alternative handling of
     * uncaught exceptions.
     *
     * @param   t   the thread that is about to exit.
     * @param   e   the uncaught exception.
     * @since   JDK1.0
     */
    public void uncaughtException(Thread t, Throwable e) {
        if (parent != null) {
            parent.uncaughtException(t, e);
        } else {
            Thread.UncaughtExceptionHandler ueh =
                Thread.getDefaultUncaughtExceptionHandler();
            if (ueh != null) {
                ueh.uncaughtException(t, e);
            } else if (!(e instanceof ThreadDeath)) {
                System.err.print("Exception in thread \""
                                 + t.getName() + "\" ");
                e.printStackTrace(System.err);
            }
        }
    }

4.2相关API
java.lang.Thread
4.2.1 public static void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler)
4.2.2 public static Thread.UncaughtExceptionHandler getDefaultUncaughtExceptionHandler()
4.3.3 public void setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)
4.4.4 public Thread.UncaughtExceptionHandler getUncaughtExceptionHandler()

java.lang.Thread.UncaughtExceptionHandler
4.2.5 void uncaughtException(Thread t,Throwable e)当给定线程因给定的未捕获异常而终止时,调用该方法。 Java 虚拟机将忽略该方法抛出的任何异常。

java.lang.ThreadGroup
4.2.6 public void uncaughtException(Thread t,Throwable e)当此线程组中的线程因为一个未捕获的异常而停止,并且线程没有安装特定 Thread.UncaughtExceptionHandler 时,由 Java Virtual Machine 调用此方法。

ThreadGroup 的 uncaughtException 方法执行以下操作:
1.如果此线程组有一个父线程组,那么调用此父线程组的 uncaughtException 方法时带有两个相同的参数。
2.否则,此方法将查看是否安装了默认的未捕获异常处理程序,如果是,则在调用其 uncaughtException 方法时带有两个相同的参数。
3.否则,此方法将确认 Throwable 参数是否为一个 ThreadDeath 实例。如果是,则不会做任何特殊的操作。否则,在从线程的 getName 方法返回时,会使用 Throwable 的 printStackTrace 方法,将包含线程名称的消息和堆栈跟踪信息输出到标准错误流。
应用程序可以重写 ThreadGroup 的子类中的方法,以提供处理未捕获异常的替代办法。

线程同步

Copyright © 2019- yule263.com 版权所有

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务