线程基础

本文深入解析Java线程的六大状态,包括new、runnable、blocked、waiting、timed-waiting及terminated,并对比线程与进程的区别。同时探讨了线程创建、线程间通信、优先级设置以及后台线程的概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 线程和进程的区别:线程是进程的执行单位,多线程之间可以共享一个进程资源,线程占用过多资源会使整个进程宕机,由于资源共享,现场之间会互相影响,进程之间通常不会。
  • 线程的的创建,都要通过java.lang.Thread类的start()方法,通常可以通过继承并扩展Thread原本的run()方法,或者实现Runnable接口的任务实体作为参数传入,线程是的启动是在调用Thread.start()时,这个方法调用本地方法(JNI),来实现一个真正意义上的线程,JVM中分配的Thread对象,只是对应OS创建的线程的外壳而已,线程使用的是堆外的空间。Runnable与Thread配合使用的意义在于,将线程和任务分离。Runnable是任务。
  • 线程的6个状态:new,runnable,blocked,waiting,timed-waiting,terminated
 - @since   1.5
     * @see #getState
     */
    public enum State {
        /**
         * Thread state for a thread which has not yet started.
         * 此时还没有调用start方法,实际上并没有创建线程
         */
        NEW,

        /**
         * Thread state for a runnable thread.  A thread in the runnable
         * state is executing in the Java virtual machine but it may
         * be waiting for other resources from the operating system
         * such as processor.
         * start()结束后,变为次状态,可以理解为存活着正尝试争用CPU的线程
         * 如运行中的线程发生yield()让步操作,线程还是runnable状态,但是它并没有占用CPU了
         */
        RUNNABLE,

        /**
         * Thread state for a thread blocked waiting for a monitor lock.
         * A thread in the blocked state is waiting for a monitor lock
         * to enter a synchronized block/method or
         * reenter a synchronized block/method after calling
         * {@link Object#wait() Object.wait}.
         * 阻塞状态,或者说挂起,原因通常是在等待一个锁,当synchronized正好有线程在使用时,一个线程尝试进入这个临界区就会被阻塞,知道另一个线程走完临界区或者发生了相应锁对象的wait操作后,才有进入的权利恢复到runnable
         * interrupt()也不能唤醒阻塞的线程,只是做了唤醒动作的标记而已,isInterrupt()可以获得结果,
         * 1.6版本后interrupted()也可以获得结果,不同的是这个方法调用后会将标记重置为false
         */
        BLOCKED,

        /**
         * Thread state for a waiting thread.
         * A thread is in the waiting state due to calling one of the
         * following methods:
         * <ul>
         *   <li>{@link Object#wait() Object.wait} with no timeout</li>
         *   <li>{@link #join() Thread.join} with no timeout</li>
         *   <li>{@link LockSupport#park() LockSupport.park}</li>
         * </ul>
         *
         * <p>A thread in the waiting state is waiting for another thread to
         * perform a particular action.
         *
         * For example, a thread that has called <tt>Object.wait()</tt>
         * on an object is waiting for another thread to call
         * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
         * that object. A thread that has called <tt>Thread.join()</tt>
         * is waiting for a specified thread to terminate.
         * 通常是线程拥有对象锁进入相应代码区后,调用对应锁对象的wait()产生的后果,变相的实现还有LockSupport.park(),Thread.join()等,他们也是在等待另一个对象时间的发生。经典例子就是 消费者和生产者。对锁对象做了notify()动作将从等待池唤醒一个线程恢复到runnable,notifyAll()唤醒全部线程。
         * 在这种情况下和TIMED_WAITING调用interrupt()是有用的,线程内部会抛出interrupt异常,应当在run方法中捕获做对应处理。
         */
        WAITING,

        /**
         * Thread state for a waiting thread with a specified waiting time.
         * A thread is in the timed waiting state due to calling one of
         * the following methods with a specified positive waiting time:
         * <ul>
         *   <li>{@link #sleep Thread.sleep}</li>
         *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
         *   <li>{@link #join(long) Thread.join} with timeout</li>
         *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
         *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
         * </ul>
         * Object.wait()有两个重构方法,可设置时间,此时状态为TIMED_WAITING
         * Thread.sleep(),LockSupport.park()等的重构方法也可以达到这样的状态
         */
        TIMED_WAITING,

        /**
         * Thread state for a terminated thread.
         * The thread has completed execution.
         * run()方法走完,此时线程可能已经被操作系统注销,这个状态只是JAVA的状态
         */
        TERMINATED;
    }
  • suspend()/resume()和stop(),join()
  • suspend()/resume()类似wait()/notify(),但是已经不建议使用,因为suspend()后状态还是runnable,不是基于对象实现,suspend和resume的顺序性不能保证。如线程在resume之后才执行到suspend()就一直停止在那了。
  • stop()和interrupt()相比,非常暴力,可对runnable操作,抛出java.lang.ThreadDeath的error。
  • join()线程合并,类似blocked的效果,只不过是等待run()结束。一般用于结果的计算
  • 优先级,java给线程设置了1-10个优先级,但是不同的os有不用的设置,有些可能只有3个或者5个优先级,所有Java中相邻的两个优先级在实际场景中可能是同一个,所以java.lang.Thread中设置三个优先级,默认NORM_PRIORITY ,可以通过setPriority(int)来设置
  /**
     * 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;
  • 还有一种特殊线程叫后台线程,可以通过setDaemon(boolean)设置,他的优先级非常低,例如JVM的GC线程,它的重要特征是,当JVM进程中只有后台线程活着时,JVM进程将结束。
  • setUncaughtExceptionHandler(exceptionHandler)是java给线程提供的一个后悔药,对run中没有捕获的异常错误的一次补救,但通常不依赖这中方式
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值