当前位置: 首页 > article >正文

【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");
    }
}

查看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 */
            }
        }
    }

查看start0()方法

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

    private native void start0();

查看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));
}

查看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

 其中有一行

native_thread = new JavaThread(&thread_entry, sz);

 有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);
 }

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

template(run_method_name,"run")

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

@Override
public void run() 
{    
    if (target != null)
    {        target.run();    }
}

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

private Runnable target;

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

public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

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


http://www.kler.cn/a/132782.html

相关文章:

  • 三周精通FastAPI:42 手动运行服务器 - Uvicorn Gunicorn with Uvicorn
  • MATLAB实现GARCH(广义自回归条件异方差)模型计算VaR(Value at Risk)
  • JAVA-链表
  • 开源科学工程技术软件介绍 – EDA工具KLayout
  • 【C++笔记】C++三大特性之多态
  • 风电电力系统低碳调度论文阅读第一期
  • SpringBoot整合Thymeleaf
  • C语言实现冒泡排序(超详细)
  • 使用FFmpeg合并多个ts视频文件转为mp4格式
  • 网站页头被挂马状态及新增了index.html文件解决思路
  • MacOS设置JAVA_HOME环境变量
  • Linux学习命令之source
  • 前端mockjs使用方式[express-mockjs]
  • 各类软件docker安装
  • torch - FloatTensor标签(boolean)数值转换(1/0)
  • QTcpSocket发送结构体的做法
  • Redis新操作
  • 12-使用vue2实现todolist待办事项
  • JS 读取excel文件内容 和 将json数据导出excel文件
  • Flume学习笔记(1)—— Flume入门
  • 计算机毕业论文内容参考|基于深度学习的交通标识智能识别系统的设计与维护
  • BeautifulReport测试报告框架
  • Vite - 配置 - 文件路径别名的配置
  • ubuntu20.04中编译zlib1.2.11(源码编译)
  • Linux网络之传输层协议tcp/udp
  • 基于数据库(MySQL)与缓存(Redis)实现分布式锁