Java并发编程-线程基础( 四 )

JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread))JVMWrapper("JVM_StartThread");JavaThread *native_thread = NULL;bool throw_illegal_thread_state = false;{MutexLocker mu(Threads_lock);if (java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread)) != NULL) {throw_illegal_thread_state = true;} else {// We could also check the stillborn flag to see if this thread was already stopped, but// for historical reasons we let the thread detect that itself when it starts running// <1> :获取当前进程中线程的数量jlong size =java_lang_Thread::stackSize(JNIHandles::resolve_non_null(jthread));size_t sz = size > 0 ? (size_t) size : 0;// <2> :真正调用创建线程的方法native_thread = new JavaThread(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());}assert(native_thread != NULL, "Starting null thread?");if (native_thread->osthread() == NULL) {// No one should hold a reference to the 'native_thread'.delete native_thread;if (JvmtiExport::should_post_resource_exhausted()) {JvmtiExport::post_resource_exhausted(JVMTI_RESOURCE_EXHAUSTED_OOM_ERROR | JVMTI_RESOURCE_EXHAUSTED_THREADS,"unable to create new native thread");}THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(),"unable to create new native thread");}// <3> 启动线程Thread::start(native_thread);JVM_ENDJVM_ENTRY 是用来定义 JVM_StartThread 函数的 , 在这个函数里面创建了一个真正和平台有关的本地线程, 上述标记 <2> 处

  • 为了进一步线程创建 , 我们在进入 new JavaThread( 来实现线程的创建 , 对于这个方法不同平台有不同的实现 , 这里不再赘述 ,

Java并发编程-线程基础文章插图
  • 上面都是创建过程 , 之后再调用 Thread::start(native_thread); 在 JVM_StartThread 中调用 , 该方法的实现在 Thread.cpp 中

Java并发编程-线程基础文章插图
start 方法中有一个函数调用: os::start_thread(thread);, 调用平台启动线程的方法 , 最终会调用 Thread.cpp 文件中的 JavaThread::run() 方法
3.2 线程的终止3.2.1 通过标记位来终止线程
  • 正常我们线程内的东西都是循环执行的 , 那么我们实际需求中肯定也存在想在其他线程来停止当前线程的需要 , 这是后我们可以通过标记位来实现 , 所谓的标记为其实就是 volatile 修饰的变量 , 是由它的可见性特性决定的 , 如下代码就是依据 volatile 来实现标记位停止线程
//定义标记为 使用 volatile 修饰private static volatileboolean mark = false;@Testpublic void markTest(){new Thread(() -> {//判断标记位来确定是否继续进行while (!mark){try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("线程执行内容中...");}}).start();System.out.println("这是主线程走起...");try {TimeUnit.SECONDS.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}//10秒后将标记为设置 true 对线程可见 。 用volatile 修饰mark = true;System.out.println("标记位修改为:"+mark);}


推荐阅读