1. Java线程的基础储备

目录:
  1. 线程的基本状态
  2. 基础操作
基本状态

进程和线程的关联: 在《高并发程序设计》中,作者的比喻十分巧妙。

进程是一个容器,比如一间明亮的小别墅,里面的电视、厨房、洗手间等都是临界资源,一家三口各为独立线程,当他们各司其职,互不干扰,比如,妈妈在厨房做饭,爸爸在书房工作,女儿在客厅看卡通节目,一家其乐融融,小别墅的生活就十分惬意。但当爸爸想去客厅看体育频道时,就和女儿产生了资源的竞争,这就是我们需要解决的冲突。

这里有个面试常出现的点:为什么并发程序设计使用多线程而不是多进程?

  1. 线程是程序最小执行单位;

  2. 线程间的切换和调度成本远小于进程;

线程的状态在Thread的State枚举中:
线程状态

public enum State {
        /**
         * Thread state for a thread which has not yet started.
         */
        // 线程刚创建,还未执行
        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.
         */
        // 线程所需资源都已就位
        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同步块阻塞,暂停执行,直到获得锁
        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() -> notify()唤醒,join() -> 等待目标线程终止,LockSupport.park(),进入无时间限制的等待
        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>
         */
        // 进入有时限的等待, 调用sleep(Long),wait(Long),join(Long)
        TIMED_WAITING,

        /**
         * Thread state for a terminated thread.
         * The thread has completed execution.
         */
        TERMINATED;
    }
基本操作
  • 新建线程

    1. 继承Thread,重写run(), 或使用匿名内部类重写run()方法

      //jdk8之前
      Thread t1 = new Thread(){
          @Override
          public void run() {
              System.out.println("hello");
          }
      };
      t1.start();
      
      // jdk8之后
      new Thread(() -> System.out.println("hello")).start();
      
    2. 实现Runnable接口,实现run():

      public class CreateThread implements Runnable {
          @Override
          public void run() {
              System.out.println("hello");
          }
          public static void main(String[] args) {
              CreateThread createThread = new CreateThread();
              Thread t1 = new Thread(createThread);
              // createThread.start(); 无此方法,start()由Thread类独有
              t1.start();
          }
      }
      
    3. 实现Callable(),实现call(),有返回值,可抛出异常:

      public class CreateThread implements Callable {
          @Override
          public Object call() throws Exception {
              return "hello";
          }
          
          public static void main(String[] args) {
              CreateThread createThread = new CreateThread();
              FutureTask futureTask = new FutureTask(createThread);
      
              Thread thread = new Thread(futureTask).s;
              thread.start();
              System.out.println(futureTask.get());
          }
      }
      
  • 启动线程

    Warning:使用Thread的start()方法启动线程,而不是run()。若执行run(), 相当于在当前线程,执行常规的方法调用。

    使用实现Runnable接口创建线程,更为合理,理由如下:

    1. 在java中,继承是很宝贵的资源,为单继承;
    2. 以下为Thread.run()源码,target为Runnable实例,因此使用实现Runnable接口创建线程,更为合理
    /**
         * If this thread was constructed using a separate
         * <code>Runnable</code> run object, then that
         * <code>Runnable</code> object's <code>run</code> method is called;
         * otherwise, this method does nothing and returns.
         * <p>
         * Subclasses of <code>Thread</code> should override this method.
         *
         * @see     #start()
         * @see     #stop()
         * @see     #Thread(ThreadGroup, Runnable, String)
         */
        @Override
        public void run() {
            if (target != null) {
                target.run();
            }
        }
    
  • 中断线程

    通过设置中断标志位状态,在业务代码中,可执行善后工作

    与线程中断相关,有三个方法

    1. interrupt()

    2. isInterrupted()

      @Override
      public void run() {
          while(true) {
              if (Thread.currentThread().isInterrupted()) {
                  System.out.println("Interrupted");
                  break;
              }
          }
      }
      
    3. Thread.interrupted() //静态方法,判断是否中断,并清除当前中断状态

    warning: wait()及sleep()操作,当等待/阻塞时,如果被中断,会抛出InterruptedException,并清除中断标记。

  • 终止线程

    使用中断代替强制终止

    java中存在一个被废弃的stop(),理由是他太过于暴力,可能引起数据不一致的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值