• 【Java并发编程三】线程的基本使用一


    基本使用一

     将类继承Runnable,创建Thread,然后调用Thread的start方法启动:

    package myTest;
    
    public class myTest implements Runnable {
    
        public static void main(String[] args) throws InterruptedException {
            myTest test = new myTest();
            Thread thread = new Thread(test);
            System.out.println(thread.getState());
            thread.start();
            System.out.println(thread.getState());
            thread.sleep(1000);
            System.out.println(thread.getState());
    
        }
        public String sout() {
            return "test";
        }
        @Override
        public void run() {
            System.out.println(this.sout());
            // System.out.println("runnning");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    查看Thread的start()方法

        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 */
                }
            }
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    查看start0()方法

     我们发现这里有一个Native关键字。Native Method就是一个java调用非java代码的接口。
     一个Native Method是这样一个java的方法:该方法是一个原生态方法,方法对应的实现不是在当前文件,而是在用其他语言(如C和C++)实现的文件中。

        private native void start0();
    
    • 1

    查看native native void start0()

     这是一个c++函数,几乎包含在thread类中的所有操作。

    /* openjdk\jdk\src\share\native\java\lang\Thread.c */
    
    #include "jni.h"
    #include "jvm.h"
    
    #include "java_lang_Thread.h"
    
    #define THD "Ljava/lang/Thread;"
    #define OBJ "Ljava/lang/Object;"
    #define STE "Ljava/lang/StackTraceElement;"
    #define STR "Ljava/lang/String;"
    
    #define ARRAY_LENGTH(a) (sizeof(a)/sizeof(a[0]))
    
    static JNINativeMethod methods[] = {
        {"start0",           "()V",        (void *)&JVM_StartThread},
        {"stop0",            "(" OBJ ")V", (void *)&JVM_StopThread},
        {"isAlive",          "()Z",        (void *)&JVM_IsThreadAlive},
        {"suspend0",         "()V",        (void *)&JVM_SuspendThread},
        {"resume0",          "()V",        (void *)&JVM_ResumeThread},
        {"setPriority0",     "(I)V",       (void *)&JVM_SetThreadPriority},
        {"yield",            "()V",        (void *)&JVM_Yield},
        {"sleep",            "(J)V",       (void *)&JVM_Sleep},
        {"currentThread",    "()" THD,     (void *)&JVM_CurrentThread},
        {"countStackFrames", "()I",        (void *)&JVM_CountStackFrames},
        {"interrupt0",       "()V",        (void *)&JVM_Interrupt},
        {"isInterrupted",    "(Z)Z",       (void *)&JVM_IsInterrupted},
        {"holdsLock",        "(" OBJ ")Z", (void *)&JVM_HoldsLock},
        {"getThreads",        "()[" THD,   (void *)&JVM_GetAllThreads},
        {"dumpThreads",      "([" THD ")[[" STE, (void *)&JVM_DumpThreads},
        {"setNativeName",    "(" STR ")V", (void *)&JVM_SetNativeThreadName},
    };
    
    #undef THD
    #undef OBJ
    #undef STE
    #undef STR
    
    JNIEXPORT void JNICALL
    Java_java_lang_Thread_registerNatives(JNIEnv *env, jclass cls)
    {
        (*env)->RegisterNatives(env, cls, methods, ARRAY_LENGTH(methods));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    查看JVM_StartThread

     发现它被一个叫做JVM_ENTRY给调用

    JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread))
      JVMWrapper("JVM_StartThread");
      JavaThread *native_thread = NULL;
      bool throw_illegal_thread_state = false;
    
      // We must release the Threads_lock before we can post a jvmti event
      // in Thread::start.
      {
        MutexLocker mu(Threads_lock);
        if (java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread)) != NULL) {
          throw_illegal_thread_state = true;
        } else {
          jlong size =
                 java_lang_Thread::stackSize(JNIHandles::resolve_non_null(jthread));
          size_t sz = size > 0 ? (size_t) size : 0;
          native_thread = new JavaThread(&thread_entry, sz);
    
          if (native_thread->osthread() != NULL) {
            // Note: the current thread is not being used within "prepare".
            native_thread->prepare(jthread);
          }
        }
      }
    
      if (throw_illegal_thread_state) {
        THROW(vmSymbols::java_lang_IllegalThreadStateException());
      }
    
      Thread::start(native_thread);
    
    JVM_END
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

     其中有一行

    native_thread = new JavaThread(&thread_entry, sz);
    
    • 1

     有native_thread,那这个JavaThread将一个thread_entry这个指针放入了构造函数中:

    static void thread_entry(JavaThread* thread, TRAPS) {
        HandleMark hm(THREAD);
        Handle obj(THREAD, thread->threadObj());
        JavaValue result(T_VOID);
        JavaCalls::call_virtual(&result,obj,
        KlassHandle(THREAD,SystemDictionary::Thread_klass()),
        vmSymbolHandles::run_method_name(),    
        vmSymbolHandles::void_method_signature(),THREAD);
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

     这个vmSymbolHandles::run_method_name(),调用了run的方法:

    template(run_method_name,"run")
    
    • 1

     成功的调用了run方法。所以,thread类在jvm的实现,cpp里面:

    @Override
    public void run() 
    {    
        if (target != null)
        {        target.run();    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    这里有一个target,通过它来判断,而这个target又在哪里?

    private Runnable target;
    
    • 1

     target在thread这个类中是被runnable所定义:

    public interface Runnable {
        /**
         * When an object implementing interface Runnable is used
         * to create a thread, starting the thread causes the object's
         * run method to be called in that separately executing
         * thread.
         * 

    * The general contract of the method run is that it may * take any action whatsoever. * * @see java.lang.Thread#run() */ public abstract void run(); }

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

     它们之间的联系,从start到start0,再到native,再到jvm,再到cpp,其中的一个宏对象调用了run方法。

  • 相关阅读:
    docker的使用
    React搭建完整项目配置插件
    南京邮电大学电工电子基础B实验五(串联谐振电路)
    如何从现有镜像创建 Dockerfile
    SOLIDWORKS Composer位置关键帧的使用
    web 网页设计规范
    你学不好英语,可能是精神内耗太多了
    SpringCloud&架构师面试
    一张表实现类某音的视频"评论回复"功能
    什么是 KNIME Hub(2024)
  • 原文地址:https://blog.csdn.net/qq_45722630/article/details/134484964