• 线程基础知识01-Thread类,Runnable接口


    常见面试题:创建一个线程的常用方法有哪些?Thread创建线程和Runnable创建线程有什么区别?
    答案通常集中在,继承类和实现接口的差别上面;
    如果深入问一些问题:1.要执行的任务写在run()方法中,为什么要用start()方法启动?等等问题
    简单的问题还是可以回答一哈子,但是涉及到深入些的问题,就只能看看源码,才能更好的回答问题了:

    1.为啥线程要用start()方法启动?

    首先要从Thread类的源码入手:

    • Thread类实现了Runnable接口
    public
    class Thread implements Runnable {
    
    • 可以看出,Thread类里面有一个Runnable接口的元素,通过构造方法给Thread类里面的Runnable元素赋值;
       private Runnable target;
       public Thread(Runnable target) {
          init(null, target, "Thread-" + nextThreadNum(), 0);
      }
      private void init(ThreadGroup g, Runnable target, String name,
                          long stackSize, AccessControlContext acc,
                          boolean inheritThreadLocals) {
           //省略部分代码
            this.group = g;
            this.daemon = parent.isDaemon();
            this.priority = parent.getPriority();
          //......省略部分代码
            this.target = target;//注意这里的赋值操作
            setPriority(priority);
            if (inheritThreadLocals && parent.inheritableThreadLocals != null)
                this.inheritableThreadLocals =
                    ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
            /* Stash the specified stack size in case the VM cares */
            this.stackSize = stackSize;
    
            /* Set thread ID */
            tid = nextThreadID();
        }
    
    • run方法很简单,就是判断是不是通过构造函数传入了Runnable接口,可以看出,线程的方法并没有执行;
     @Override
        public void run() {
            if (target != null) {
                target.run();
            }
        }
    
    
    • start()方法中通过调用start0()执行Run()方法;类似于this.run();报错后也是忽略状态
     public synchronized void start() {
            if (threadStatus != 0)
                throw new IllegalThreadStateException();
    
            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 */
                }
            }
        }
    
        private native void start0();
    
    
    • 可以借鉴的地方:
      将任务封装在单独的接口中,可以多种实现,通过统一的方法去调用;
    interface A {
      run(){)
    }
    class B implements A {
     private A a;
     B(){}
     B(A a){this.a = a} 
     run(){
       if(a != null ){a.run} 
     }
     start(){this.run()}
    }
    
    

    2.Thread的几种状态

    • 类中给出的几种状态
    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}.
             */
            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.
             */
            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>
             */
            TIMED_WAITING,
    
            /**
             * Thread state for a terminated thread.
             * The thread has completed execution.
             */
            TERMINATED;
        }
    
    

    下面这个图能更好的理解线程的状态
    (图片来自《java并发编程艺术》)

    1.线程开启,存在两种情况,运行状态和临时阻塞状态(调用方法,但没有获取到锁的情况下);
    运行状态,具有执行资格和执行权;临时阻塞状态,只有执行资格没有执行权;
    2.线程运行完之后有两种状态:冻结/等待和TERMINATED,
    冻结状态释放执行权和执行资格。调用wait()或sleep()方法

    3.interceptor和stop之间的区别

    stop:终结一个线程不会保证资源释放,比较暴力;
    interceptor:线程被中断了,可以通过isInterceptor方法获取是否被终端;但是抛异常,或者isItercepter方法后,终端状态会被清楚;
    比较好的线程终止方案,可以增加一个标识符eg:flag=true的判断,要中断的时候,将标识符设置位false即可;

    4.什么是自旋锁?什么是无锁编程?

    CAS简单了解: https://www.cnblogs.com/perferect/p/12761558.html

    5.死锁

    死锁的定义:一组互相竞争资源的线程因互相等待,导致“永久”阻塞的现象。
    最常出现死锁的情况是,当两个或多个锁互相嵌套,一个锁内部进行其他锁的竞争;

    class test{
      private static final Object obj1 = new Object();
      private static final Object obj2 = new Obbject();    
      public static void main(String[] args){
          new Thread(){
            public void run(){
              synchronized(obj1){
                   Thread.sleep(100);
                   synchronized(obj2){
                       Thread.sleep(200);
                     }   
               } 
            }
          }.start();
          new Thread(){
            public void run(){
              synchronized(obj2){
                   Thread.sleep(100);
                   synchronized(obj1){
                       Thread.sleep(200);
                     }   
               } 
            }
          }.start();      
    
      }  
    }
    
  • 相关阅读:
    表的数据类型
    SQLYog Enterprise注册码分享
    MySQL下载安装、基本配置、问题处理
    windows下命令行模式中cd命令无效的原因
    TCP协议三次握手与四次挥手通俗解析
    使用concurrent.futures模块并发,实现进程池、线程池
    进程池、线程池、回调函数
    浅谈web网站架构演变过程
    memcached单点故障与负载均衡
    memcached性能监控
  • 原文地址:https://www.cnblogs.com/perferect/p/12967365.html
Copyright © 2020-2023  润新知