比如一个 ThreadDemo 类实现了 Runnable 接口,我在 main 函数中创建了一个 ThreadDemo 类实例,并用这个实例创建了两个线程。 当我在 ThreadDemo 中定义了一个 private int count 属性时,请问这个变量在两个线程栈中都有存储吗?还是说这个变量存储在另外的地方?如果我在 ThreadDemo 中定义了 private String name 时又是怎么样的?
1
momocraft 2019-04-11 14:59:44 +08:00
field 是对象的一部分,一定不在栈上,**对象的引用** 才可能在栈上
这已经和线程没关系了.. |
2
misaka19000 2019-04-11 15:07:27 +08:00 via Android
上代码
|
3
gosansam 2019-04-11 15:15:42 +08:00
个人感觉共享变量存在主存中,各个使用会去拉副本到线程栈
|
4
liuxey 2019-04-11 15:19:46 +08:00
首先你的案例里没有资源共享的情况,两个 ThreadDemo 实例都有自己的 count,各不相干
其次 String 也是一样的 |
5
gaius 2019-04-11 15:26:59 +08:00
new 一个实例是怎么开的 2 个线程?
|
6
lhx2008 2019-04-11 15:30:14 +08:00
栈上面就没有共享的事情
|
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 2019-04-11 15:55:35 +08:00
应该只有 main 线程的栈中持有对 threadDemo 对象的引用吧
|
9
Michlix 2019-04-11 16:07:31 +08:00
|
10
domty 2019-04-11 16:17:37 +08:00
对象都是分配在堆上的
即便是线程持有的也只是这个对象的一个引用 |
11
hailiang88 2019-04-11 16:29:26 +08:00
1、如果是类的成员变量的话会存在 Method Area,这个区域是线程共享的
2、如果是局部变量的话会存在于 Stack Area,可以了解下栈帧( stack frame ),这个是线程私有的 [https://liang.im/index.php/archives/3/]( https://liang.im/index.php/archives/3/) |
12
DanielGuo 2019-04-11 16:30:51 +08:00
@mart1nN 在我的理解中,t1 和 t2 都是一个对象,这两个对象都在堆中存在,t1 和 t2 的实例变量有对 threadDemo 的引用
|
13
zifangsky 2019-04-11 17:55:25 +08:00
1、堆、栈的概念跟线程没有关系。
2、对象在堆空间( Heap space )实例化,成员变量 count 自然也在堆空间中,且 new 一次只实例化一次。 3、之所以多个线程对成员变量 count 执行写操作会有线程安全问题,那是因为多个线程在对同一片内存区域的 count 变量进行操作。 |
14
v2qwsdcv 2019-04-11 19:45:03 +08:00
源码给您找好啦,求别鄙视我们做 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 2019-04-11 20:01:10 +08:00
另 #13 说的对
|
16
troywinter 2019-04-12 00:32:12 +08:00
看了这个帖子我还以为搞了十年的 PLT 都是假的,直到看到了#13 楼
|
17
gramyang 2019-04-13 08:37:01 +08:00
兄啊,刚刚测试了一下,这个 demo 并不会出现乱序
|