精华内容
下载资源
问答
  • Java如何获取当前线程

    万次阅读 2018-07-05 08:26:48
    Java 中经常会遇到要获取当前线程的情况,这时一般我们就会通过Thread.currentThread()来获取,接下去就看看执行该语句在 JVM 中做了什么吧。 简单例子 以下是一个简单的例子,获取当前线程并打印线程名称,输出...

    前言

    Java 中经常会遇到要获取当前线程的情况,这时一般我们就会通过Thread.currentThread()来获取,接下去就看看执行该语句在 JVM 中做了什么吧。

    简单例子

    以下是一个简单的例子,获取当前线程并打印线程名称,输出是”main”,即主线程。

    public class CurrentThreadTest {
    
        public static void main(String[] args) {
            Thread t = Thread.currentThread();
            System.out.println(t.getName());
        }
    
    }

    currentThread方法

    在 Thread 类中,currentThread是一个静态且本地方法。

    public static native Thread currentThread();

    Thread.c

    Java 层声明的本地方法对应实现在 Thread.c 中,currentThread是一个注册到 JVM 中的方法,它与 JVM 中的JVM_CurrentThread函数绑定了,所以实现逻辑在JVM_CurrentThread函数里。逻辑为:
    * JVMWrapper("JVM_CurrentThread")用于调试。
    * 通过thread->threadObj()获取 oop,这里的 thread 是在JNI_ENTRY宏中获取到的,详细情况可参考后面的JNI_ENTRYJNI_END宏。
    * 调用JNIHandles::make_local函数

    #define THD "Ljava/lang/Thread;"
    
    static JNINativeMethod methods[] = {
        ...
        {"currentThread",    "()" THD,     (void *)&JVM_CurrentThread},
        ...
    };
    
    JVM_ENTRY(jobject, JVM_CurrentThread(JNIEnv* env, jclass threadClass))
      JVMWrapper("JVM_CurrentThread");
      oop jthread = thread->threadObj();
      assert (thread != NULL, "no current thread!");
      return JNIHandles::make_local(env, jthread);
    JVM_END

    make_local函数中主要看thread_from_jni_environment函数,它用于获取当前线程,它的逻辑为JavaThread *thread_from_jni_env = (JavaThread*)((intptr_t)env - in_bytes(jni_environment_offset()));,即直接通过地址偏移来做减法计算得到JavaThread*,这是因为 JavaThread 对象包含了 JNIEnv 对象属性,所以可以通过JNIEnv*与偏移做减法来算出JavaThread*。最后还要检查线程是否已经终止状态,没有终止才返回该线程对象。

    获取到JavaThread*对象后,分配句柄并将 oop 赋给句柄,并且转成 Java 层的对象 jobject。

    jobject JNIHandles::make_local(JNIEnv* env, oop obj) {
      if (obj == NULL) {
        return NULL;                
      } else {
        JavaThread* thread = JavaThread::thread_from_jni_environment(env);
        assert(Universe::heap()->is_in_reserved(obj), "sanity check");
        return thread->active_handles()->allocate_handle(obj);
      }
    }
    
    static JavaThread* thread_from_jni_environment(JNIEnv* env) {
        JavaThread *thread_from_jni_env = (JavaThread*)((intptr_t)env - in_bytes(jni_environment_offset()));
        if (thread_from_jni_env->is_terminated()) {
          thread_from_jni_env->block_if_vm_exited();
          return NULL;
        } else {
          return thread_from_jni_env;
        }
      }

    JNI_ENTRYJNI_END

    这两个宏将共同的部分都抽离出来了。其中JNI_END比较简单,就两个结束大括号。

    #define JNI_ENTRY(result_type, header)  JNI_ENTRY_NO_PRESERVE(result_type, header)    WeakPreserveExceptionMark __wem(thread);
    
    #define JNI_END } }

    JNI_ENTRY主要逻辑:
    * 获取当前执行线程 JavaThread 指针对象。
    * 创建 ThreadInVMfromNative 对象。
    * TRACE_CALL ,这里什么都不干。
    * 创建 HandleMarkCleaner 对象。
    * 将 thread 赋值给 Exceptions 中的 THREAD。
    * 校验栈对齐。
    * 创建 WeakPreserveExceptionMark 对象。

    #define JNI_ENTRY_NO_PRESERVE(result_type, header)                   \
    extern "C" {                                                         \
      result_type JNICALL header {                                       \
        JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
        assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \
        ThreadInVMfromNative __tiv(thread);                              \
        debug_only(VMNativeEntryWrapper __vew;)                          \
        VM_ENTRY_BASE(result_type, header, thread)
    
    #define VM_ENTRY_BASE(result_type, header, thread)                   \
      TRACE_CALL(result_type, header)                                    \
      HandleMarkCleaner __hm(thread);                                    \
      Thread* THREAD = thread;                                           \
      os::verify_stack_alignment();      

    ————-推荐阅读————

    我的2017文章汇总——机器学习篇

    我的2017文章汇总——Java及中间件

    我的2017文章汇总——深度学习篇

    我的2017文章汇总——JDK源码篇

    我的2017文章汇总——自然语言处理篇

    我的2017文章汇总——Java并发篇


    跟我交流,向我提问:

    这里写图片描述

    公众号的菜单已分为“读书总结”、“分布式”、“机器学习”、“深度学习”、“NLP”、“Java深度”、“Java并发核心”、“JDK源码”、“Tomcat内核”等,可能有一款适合你的胃口。

    为什么写《Tomcat内核设计剖析》

    欢迎关注:

    这里写图片描述

    展开全文
  • 如何中断当前线程

    2017-11-10 16:39:37
    如何中断当前线程中断当前线程有两种方式。第一种方式是通过调用线程的stop()方法,第二种方式通过调用interrupt()方法。 由于第一种方式是不安全的,所以本篇文章不做讨论,主要分享一下如何使用interrupt()方法来...

    如何中断当前线程

    中断当前线程有两种方式。第一种方式是通过调用线程的stop()方法,第二种方式通过调用interrupt()方法。
    由于第一种方式是不安全的,所以本篇文章不做讨论,主要分享一下如何使用interrupt()方法来中断线程。

    采用interrupt中止线程

    Thread类中提供了三个中断线程的方法,如下图:
    这里写图片描述
    这里写图片描述
    方法详情:

    • interrupt():中断当前线程。该方法仅设置当前线程的状态为中断,实际上并不中断线程的运行。如果要中断线程的运行,还需要当前线程自己中断
    • interrupted():测试当前线程的状态是否被中断。使用这个方法会清除当前线程的状态。简言之,如果这个方法被调用了两次,那么第二次会返回false. 除非当前线程在第二次调用之前,第一次清除线程状态之后,再次再中断。
    • isInterrupted():测试当前线程的状态是否被中断。这个方法与interrupted()这个方法最大的差异是isInterrupted()方法不会清除当前线程的状态。

    代码示例

    public class ThreadInterruptDemo implements Runnable {
    
        @Override
        public void run() {
    
    //        System.out.println("第一次调用Thread.interrupted()" + Thread.interrupted());
    //        System.out.println("第二次调用Thread.interrupted()" + Thread.interrupted());
    
            /**
             * isInterrupted()
             * 用来测试当前线程的运行状态
             * true:表示当前线程为中断状态
             * false:表示当前线程为运行状态
             * 可以通过这样的方法来中断线程运行
             */
            if (Thread.currentThread().isInterrupted()){
                System.out.println("由于线程状态是中断,所以return不再执行线程任务");
                return;
            }
    
            while (true) {
                try {
                    Thread.sleep(3L);
                    System.out.println("线程正在执行");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    break;
                }
            }
    
        }
    
        public static void main(String[] args) {
            Thread thread = new Thread(new ThreadInterruptDemo(), "ThreadInterruptDemo");
            // 开启线程
            thread.start();
    
            /**
             * 中断当前线程
             * 该方法仅设置当前线程的状态为中断,实际上并不中断线程的运行
             * 如果要中断线程的运行,还需要当前线程自己中断
             */
            thread.interrupt();
        }
    
    }

    源代码链接:
    https://github.com/myNameIssls/javase-study/blob/master/javase-multithreading/src/main/java/cn/tyrone/javase/thread/ThreadInterruptDemo.java
    参考链接:
    https://docs.oracle.com/javase/8/docs/api/
    https://www.cnblogs.com/w-wfy/p/6414801.html
    http://blog.csdn.net/paincupid/article/details/47626819

    展开全文
  • 这篇学习关于Thread类的两个方法,第一个是获取当前线程对象,返回的是一个Thread对象。第二个方法是我们自动化中经常使用的,线程休眠。 1.currentThread() 获取的是当前线程对象,是对象不是对象名称,如果要...

    这篇学习关于Thread类的两个方法,第一个是获取当前线程对象,返回的是一个Thread对象。第二个方法是我们自动化中经常使用的,线程休眠。

    1.currentThread()

    获取的是当前线程对象,是对象不是对象名称,如果要获取名称,需要对象.getName()实现。

    package thread;
    
    public class Demo5_Thread {
    
    	public static void main(String[] args) {
    		
    		new Thread() {
    			public void run() {
    				System.out.println(this.getName() +": aaaaa");
    			}
    		}.start();
    		
    		new Thread(new Runnable() {
    			
    			public void run() {
    				System.out.println(Thread.currentThread().getName()+": bbbb");
    			}
    		}).start();
    		
    		//main方法打印线程名称
    		System.out.println(Thread.currentThread().getName());
    	}
    
    }
    

    运行结果:

    Thread-0: aaaaa
    main
    Thread-1: bbbb
    

    这个打印结果,也说明了,多线程中,main方法本身就是一个单独线程执行,而且执行顺序并不会像代码写的从上往下的顺序。

    2.线程休眠

    休眠就是让线程停顿下来,支持不同时间单位的中断。这个方法是Thread.sleep(xxx毫秒)。我们写自动化脚本经常需要用到它。

    package thread;
    
    public class Demo5_Thread {
    
    	public static void main(String[] args) throws InterruptedException {
    		
    		new Thread() {
    			public void run() {
    				for(int i = 0; i< 10; i ++) {
    					try {
    						Thread.sleep(1000);
    					} catch (InterruptedException e) {
    						
    						e.printStackTrace();
    					}
    					System.out.println(this.getName() +": aaaaa");
    				}
    				
    			}
    		}.start();
    		
    		new Thread(new Runnable() {
    			
    			public void run() {
    				for(int i = 0; i< 10; i ++) {
    					try {
    						Thread.sleep(1000);
    					} catch (InterruptedException e) {
    						
    						e.printStackTrace();
    					}
    					System.out.println(Thread.currentThread().getName()+": bbbb");
    				}
    				
    			}
    		}).start();
    		
    		//main方法打印线程名称
    		System.out.println(Thread.currentThread().getName());
    	}
    
    }
    

    运行之后,可以看到间隔一秒输出一个。

    展开全文
  • QT获取当前线程ID

    万次阅读 2019-09-25 09:01:43
    QT获取当前线程ID 用QSerialPort串口类的时候出现了: [WARNING ] QObject: Cannot create children for a parent that is in a different thread. (Parent is QSerialPort(0x505f250), parent’s thread is QThread...

    QT获取当前线程ID

    用QSerialPort串口类的时候出现了:
    [WARNING ] QObject: Cannot create children for a parent that is in a different thread.
    (Parent is QSerialPort(0x505f250), parent’s thread is QThread(0x2b7ff0), current thread is QThread(0x563a860)

    于是想要输出一下到底现在是在哪个线程里跑,不废话,直接上代码:

     QString LogInfo;
        LogInfo.sprintf("%p", QThread::currentThread());
        qDebug() << "OpenSerialPort " <<"threadID : "<<LogInfo;
    
    展开全文
  • C#中如何判断当前线程是否为主线程

    千次阅读 2016-11-25 16:44:21
    转自:C#中如何判断当前线程是否为主线程 / Do this when you start your application static int mainThreadId; // In Main method: mainThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId...
  • Linux最大线程数限制及当前线程数查询 1、总结系统限制有: /proc/sys/kernel/pid_max #查系统支持的最大线程数,一般会很大,相当于理论值 /proc/sys/kernel/thread-max max_user_process(ulimit -u) #系统...
  • Java多线程-当前线程副本:ThreadLocal

    千次阅读 2016-06-16 20:27:53
    一般情况我们创建的变量是可以被任何一个线程访问并修改的,而使用ThreadLocal创建的变量只能被当前线程访问,其他线程无法访问和修改。 ThreadLocal<T> 接口的方法也很简单,只有四个方法: public class ...
  • 使当前线程暂停的方法

    千次阅读 2019-07-08 15:25:44
    /*使当前线程暂停的方法 Thread类下: * public static void sleep(long millis) 使当前正在运行的进程暂停millis毫秒 * */ public class Demo03 { public static void main(String[] args) { for ...
  • 如何判断当前线程是主线程

    千次阅读 2018-09-05 23:04:14
    在iOS中如何准确判断当前线程是主线程
  • eclipse 调试之停止当前线程

    千次阅读 2018-07-31 14:59:21
    在eclipse中调试java的时候,如果不想继续走下一步了, 可以采取直接抛出异常的方式直接停止当前线程 需要打开display窗口 然后直接运行这个,就会抛出异常,然后这个线程就会被停止了...
  • public static void XXX(object param) { Thread th = Thread.CurrentThread;//获取当前工作的线程 th.Abort();//强制关闭当前线程 }
  • java获得当前线程的名称

    千次阅读 2017-12-19 18:06:22
    //获得当前线程的名称 System.out.println(Thread.currentThread().getName());
  • Windows 下 GoLang 获取当前线程ID func GetCurrentThreadId() int { var user32 *syscall.DLL var GetCurrentThreadId *syscall.Proc var err error user32, err = syscall.LoadDLL("Kernel32.dll")...
  • C++11当前线程this_thread实战

    千次阅读 2019-04-13 08:30:02
    C++11提供了一个命名空间this_thread来引用当前线程,该命名空间有4个有用的函数,get_id,yield,sleep_until,sleep_for。 get_id是用来获取线程ID的。 其他3个函数都和时间相关,下面分别进行实战演练。 二yield...
  • 线程 NSThread 多线程 获取当前线程

    万次阅读 2014-02-21 18:55:19
    线程 NSThread 多线程 线程与进程 进程 是一个活动的程序,一个容器 是系统资源管理的最小单位 切换代价较高 线程 是在进程容器中运行,实际工作的代码 是程序执行的最小单位 切换代价较低(由于线程是在同一块内存...
  • 当一个优先级高的线程进入就绪状态时,当前线程执行时,如果是抢占式的调度方式,是会暂停当前线程的执行的,当仍然不是终止它的执行。当不是抢占式的调度时,高优先级的线程将在当前线程终止后,得到优先的执行权。...
  • 休眠是与放弃yield相比是更有力的放弃方式, 放弃只是表示当前线程愿意暂停当前线程,让其他有相同优先级的等待线程有机会获得cpu资源。而进入休眠sleep不同,不管有没有其他线程在等待资源,都进入暂停,这样一来...
  • Windows/Linux下获取当前线程的ID号

    千次阅读 2018-09-17 20:07:00
    在多线程场合,为了方便跟踪线程的运行状态,往往需要在程序中添加打印当前线程ID号的功能。 1. Linux下打印当前线程ID pthread_t pthread_self() 2. Windows下打印当前线程ID DWORD GetCurrentThreadId(); ...
  • 以下实例演示了如何通过继承 Thread 类并使用 getName() 方法来获取当前线程名称:public class TwoThreadGetName extends Thread { public void run() { for (int i = 0; i &lt; 10; i++) { printMsg(); }...
  • Looper判断当前线程是否是主线程

    千次阅读 2017-08-22 12:11:20
    1.判断方法可以借助Looper来判断当前线程是否是主线程:代码:public boolean isMainThread() { return Looper.getMainLooper() == Looper.myLooper(); }getMainLooper()得到的是整个application的主线程。myLooper...
  • 在windows编程中,有时候我们会遇到需要传入作用对象句柄的函数,如GetThreadTimes...GetCurrentThread()函数即可,其会返回当前线程的“伪”句柄。类似的,我们也有函数可以获得当前进程的句柄。 HANDLE GetCurrentTh
  • Android 打印当前线程的调用堆栈

    千次阅读 2017-11-15 15:20:55
    /** * 打印当前线程的调用堆栈 * */ public static void printTrack(){ StackTraceElement[] st = Thread.currentThread().getStackTrace(); if(st==null){ System.out.println
  • 判断当前线程是否UI线程

    千次阅读 2017-11-20 11:23:08
    两种方法: 1.if (Thread.currentThread() == Looper.getMainLooper().getThread()) { // UI线程 } else { // 非UI线程 } 2.if (Looper.myLooper() == Looper.getM
  • Java线程异常时,是否会把共享变量在当前线程计算结果回写主存。 在看内存模型时,说明每个线程从主存里拷贝变量到自己的工作内存里,然后进行计算,对于共享变量的操作实际都是操作自己工作内存里的。 然后会把...
  • java-实时打印当前线程的调用堆栈

    万次阅读 2017-04-26 09:47:54
    java-实时打印当前线程的调用堆栈 /** * 打印当前线程的调用堆栈 *  */ void printTrack(){ StackTraceElement[] st = Thread.currentThread().getStackTrace(); if(st==null){ System.out.println("无堆栈...");...
  • 在程序中调用窗体时,因另一个窗体包含webbrowser,因此在实例化时报错:当前线程不在单线程单元中,因此无法实例化 ActiveX,查找了下网上的一些方法,说的最多的是在入口添加[STAThread],但我一看项目本身默认创建...
  • Android开发中, 有时需要判断当前线程到底是主线程, 还是子线程, 例如: 我们在自定义View时, 想要让View重绘, 需要先判断当前线程到底是不是主线程, 然后根据判断结果来决定到底是调用 invalidate() 还

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 47,234
精华内容 18,893
关键字:

当前线程