比如一个 ThreadDemo 类实现了 Runnable 接口,我在 main 函数中创建了一个 ThreadDemo 类实例,并用这个实例创建了两个线程。 当我在 ThreadDemo 中定义了一个 private int count 属性时,请问这个变量在两个线程栈中都有存储吗?还是说这个变量存储在另外的地方?如果我在 ThreadDemo 中定义了 private String name 时又是怎么样的?
比如一个 ThreadDemo 类实现了 Runnable 接口,我在 main 函数中创建了一个 ThreadDemo 类实例,并用这个实例创建了两个线程。 当我在 ThreadDemo 中定义了一个 private int count 属性时,请问这个变量在两个线程栈中都有存储吗?还是说这个变量存储在另外的地方?如果我在 ThreadDemo 中定义了 private String name 时又是怎么样的?
1
momocraft Apr 11, 2019
field 是对象的一部分,一定不在栈上,**对象的引用** 才可能在栈上
这已经和线程没关系了.. |
2
misaka19000 Apr 11, 2019 via Android
上代码
|
3
gosansam Apr 11, 2019
个人感觉共享变量存在主存中,各个使用会去拉副本到线程栈
|
4
auin Apr 11, 2019
首先你的案例里没有资源共享的情况,两个 ThreadDemo 实例都有自己的 count,各不相干
其次 String 也是一样的 |
5
gaius Apr 11, 2019
new 一个实例是怎么开的 2 个线程?
|
6
lhx2008 Apr 11, 2019
栈上面就没有共享的事情
|
7
mart1nN OP ThreadDemo
public class ThreadDemo implements Runnable{ private int count; public ThreadDemo() { count = 0; } @Override //循环打印 public void run() { System.out.println("before syn"); synchronized (this){ for (int i = 0; i < 10; i++){ try { System.out.println(Thread.currentThread().getName() + ":" + (count++)); Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } System.out.println("after syn"); } } test //这里就写主要部分了 ThreadDemo threadDemo = new ThreadDemo(); Thread t1 = new Thread(threadDemo, "thread-01"); Thread t2 = new Thread(threadDemo, "thread-02"); t1.start(); t2.start(); t1,t2 这两个线程栈里存储了 threadDemo 实例的引用吗?还有就是 main 线程会给这两个线程初始化后这三个线程栈存储的有啥不同吗? |
8
misaka19000 Apr 11, 2019
应该只有 main 线程的栈中持有对 threadDemo 对象的引用吧
|
9
Michlix Apr 11, 2019
|
10
domty Apr 11, 2019
对象都是分配在堆上的
即便是线程持有的也只是这个对象的一个引用 |
11
hailiang88 Apr 11, 2019
1、如果是类的成员变量的话会存在 Method Area,这个区域是线程共享的
2、如果是局部变量的话会存在于 Stack Area,可以了解下栈帧( stack frame ),这个是线程私有的 [https://liang.im/index.php/archives/3/]( https://liang.im/index.php/archives/3/) |
13
zifangsky Apr 11, 2019
1、堆、栈的概念跟线程没有关系。
2、对象在堆空间( Heap space )实例化,成员变量 count 自然也在堆空间中,且 new 一次只实例化一次。 3、之所以多个线程对成员变量 count 执行写操作会有线程安全问题,那是因为多个线程在对同一片内存区域的 count 变量进行操作。 |
14
v2qwsdcv Apr 11, 2019
源码给您找好啦,求别鄙视我们做 C++的了 都不容易。
https://github.com/unofficial-openjdk/openjdk/blob/5ec14c8bb2533c20eca3564258c4dc66bf3bb9c3/src/java.base/share/classes/java/lang/Thread.java public synchronized void start() { ... try { start0(); started = true; } ... } private native void start0(); https://github.com/unofficial-openjdk/openjdk/blob/531ef5d0ede6d733b00c9bc1b6b3c14a0b2b3e81/src/java.base/share/native/libjava/Thread.c {"start0", "()V", (void *)&JVM_StartThread}, https://github.com/unofficial-openjdk/openjdk/blob/e19d12112815026f04a9df075e56eb26622b9d8d/src/hotspot/share/prims/jvm.cpp JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread)) JVMWrapper("JVM_StartThread"); JavaThread *native_thread = NULL; ... 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); } } } ... Thread::start(native_thread); JVM_END static void thread_entry(JavaThread* thread, TRAPS) { HandleMark hm(THREAD); Handle obj(THREAD, thread->threadObj()); JavaValue result(T_VOID); JavaCalls::call_virtual(&result, obj, SystemDictionary::Thread_klass(), vmSymbols::run_method_name(), vmSymbols::void_method_signature(), THREAD); } https://github.com/unofficial-openjdk/openjdk/blob/294d2d319b870ac68ca10a5b03006a70e26bcaba/src/hotspot/share/runtime/thread.cpp void JavaThread::run() { ... thread_main_inner(); } void JavaThread::thread_main_inner() { ... if (!this->has_pending_exception() && !java_lang_Thread::is_stillborn(this->threadObj())) { { ResourceMark rm(this); this->set_native_thread_name(this->get_thread_name()); } HandleMark hm(this); this->entry_point()(this, this); } ... } https://github.com/unofficial-openjdk/openjdk/blob/d148cecb01572f077179c94cb59117af89eb59b8/src/hotspot/share/runtime/javaCalls.cpp https://github.com/unofficial-openjdk/openjdk/blob/e836a10c8c6ed2ef2f3219c46ca1906a2d9d6493/src/hotspot/share/classfile/vmSymbols.hpp template(run_method_name, "run") |
15
v2qwsdcv Apr 11, 2019
另 #13 说的对
|
16
troywinter Apr 12, 2019
看了这个帖子我还以为搞了十年的 PLT 都是假的,直到看到了#13 楼
|
17
gramyang Apr 13, 2019
兄啊,刚刚测试了一下,这个 demo 并不会出现乱序
|