由买买提看人间百态

boards

本页内容为未名空间相应帖子的节选和存档,一周内的贴子最多显示50字,超过一周显示500字 访问原贴
Programming版 - 线程共享变量问题,搞不懂。
相关主题
Java的服务器一般运行几个线程比较合适?大量读HBase的任务该加线程还是进程?
关于thread的stack用volatile退出线程对不对?(C++)
问个线程同步的问题Bihai,你就用atmoic完事了
求C/C++面试题Python 多线程或多进程如何搞
问个C++编译器如何处理函数内的static 变量重复利用threads的问题
question about volatile variable on multiple coresThread Priority 设为最高--窗口最小化时好像并不优先啊?
关于线程读写全局变量的问题怎么 kill 一个 thread 啊
win 7 pro 正常情况多少进程/线程?[合集] 为什么多个线程生成的随机数是一样的?
相关话题的讨论汇总
话题: thread话题: 共享话题: 线程话题: main话题: 进程
进入Programming版参与讨论
1 (共1页)
d*********g
发帖数: 38
1
最近看java多线程郁闷了,理解不了线程之间共享进程地址空间。
举个栗子:
class M extends Thread{
int mValue=0;
public void run(){...}
}
class N extends Thread{
int nValue=1;
public void run{...}
}
class Main{
int mainValue=2;
public static void main(){
Thread m1=new M();
Thread m2=new M();
Thread n=new N();
}
}
这个例子中,Main是主进程吗?可以被m1, m2, n共享的进程空间包括什么?
我的理解有几种可能:
1. m1和m2可以共享mValue ,虽然mValue不是static的。不过我不确定这种共享是否基
于同一进程地址空间。
2. m1, m2, 和 n1可以共享mainValue (因为Main是线程,m1, m2, n1都是该线程下的
进程)。
p*****2
发帖数: 21240
2

1不行吧?

【在 d*********g 的大作中提到】
: 最近看java多线程郁闷了,理解不了线程之间共享进程地址空间。
: 举个栗子:
: class M extends Thread{
: int mValue=0;
: public void run(){...}
: }
: class N extends Thread{
: int nValue=1;
: public void run{...}
: }

d*********g
发帖数: 38
3
你这一说我也糊涂了,我觉得2似乎也不行。这样一来,两个相同class的线程(比如m1
m2)能共享什么呢?如果是两个不同class的线程呢?(比如m1和n)。

【在 p*****2 的大作中提到】
:
: 1不行吧?

d******e
发帖数: 2265
4
浆糊啊。
第一,搞清楚value和refer类型。value类型, int,是在stack上。不可能被共享。
所以,下面一个都不会被共享。
第二,一般共享的是某个类里面的某个变量。通过这个类的某个方法来实现共享。

【在 d*********g 的大作中提到】
: 最近看java多线程郁闷了,理解不了线程之间共享进程地址空间。
: 举个栗子:
: class M extends Thread{
: int mValue=0;
: public void run(){...}
: }
: class N extends Thread{
: int nValue=1;
: public void run{...}
: }

k*****u
发帖数: 136
5
我才楼主是半路出家吧
建议楼主搞清楚几个概念,进程 线程 堆 栈
什么变量存在堆中,什么变量存在栈中
为什么线程之间不能互相共享(存储在各自线程的private栈里)
为什么进程里面的变量可以被线程访问(存储在主进程的共享栈里)
所以1 是不行的,每一个实例化的m都各自含有一个mvalue 彼此独立
2你自己查查吧 写个程序就知道了
c*********e
发帖数: 16335
6
线程 和 进程 都没搞清。你半路出家的吧?

【在 d*********g 的大作中提到】
: 最近看java多线程郁闷了,理解不了线程之间共享进程地址空间。
: 举个栗子:
: class M extends Thread{
: int mValue=0;
: public void run(){...}
: }
: class N extends Thread{
: int nValue=1;
: public void run{...}
: }

d*********g
发帖数: 38
7
的确是半路出家,刚开始看多线程,一团雾水,感谢楼上几位。
那很多资料都写到“All threads of a process share its virtual address space
and system resources.”或类似的意思,这个share有什么好处呢,既然每个线程都有
自己的私有栈。
g*********e
发帖数: 14401
8
你这个也不对 java obj怎么会在stack上

【在 d******e 的大作中提到】
: 浆糊啊。
: 第一,搞清楚value和refer类型。value类型, int,是在stack上。不可能被共享。
: 所以,下面一个都不会被共享。
: 第二,一般共享的是某个类里面的某个变量。通过这个类的某个方法来实现共享。

z****e
发帖数: 54598
9

int是primitive type,不是obj,obj是Integer
还有如果我记得没错,某人说过,local inner object好像是会被放到stack里面去
好久了不太记得了,反正不是百分百obj都不会放到stack上去的
某些特殊情况下优化,就会被放进去,但是这些都属于奇淫技巧
不懂没啥关系

【在 g*********e 的大作中提到】
: 你这个也不对 java obj怎么会在stack上
k*****u
发帖数: 136
10
share的好处就是 high performance
举个例子,如果你的计算机有多个core,比如说四核,那么理论上四个core可以同时进
行计算
你有一个process,你需要处理一款很大的数据,你就把这个数据没成四块,然后
create四个thread,每个线程都去计算各自的数据,然后把数据汇总到进程中。这个过
程数据从进程到线程,再由线程回进程,就是一个共享的结果
当然share的好处不局限于此
如果是自己的pc也许只有四核 八核,如果是集群可能就是几十核,几百核,有很多高
性能的技术比如openmp(shared memory) openmpi(message passing) hadoop(
mapreduce) 都是类似的进行计算,大同小异
敢问一句,楼主开始cs的东西多久了? 说说你的打算,比起技术上的细节,最重要的
学习的方法

【在 d*********g 的大作中提到】
: 的确是半路出家,刚开始看多线程,一团雾水,感谢楼上几位。
: 那很多资料都写到“All threads of a process share its virtual address space
: and system resources.”或类似的意思,这个share有什么好处呢,既然每个线程都有
: 自己的私有栈。

相关主题
question about volatile variable on multiple cores大量读HBase的任务该加线程还是进程?
关于线程读写全局变量的问题用volatile退出线程对不对?(C++)
win 7 pro 正常情况多少进程/线程?Bihai,你就用atmoic完事了
进入Programming版参与讨论
d******e
发帖数: 2265
11
int不是obj.要变obj需要boxing/unboxing.事实上很多情况下int放在register里面。
如果都要unbox一下在放register计算,java的效率估计还不如python呢。

【在 g*********e 的大作中提到】
: 你这个也不对 java obj怎么会在stack上
g*****g
发帖数: 34805
12
没有 declare成Integer, 会放在 stack上。至于 是否用register, 是 JVM级别的处理
,没法控制。

【在 d******e 的大作中提到】
: int不是obj.要变obj需要boxing/unboxing.事实上很多情况下int放在register里面。
: 如果都要unbox一下在放register计算,java的效率估计还不如python呢。

d*********g
发帖数: 38
13
谢谢keiutou的例子。咱们就follow这个例子聊一下共享,因为我还不是很明白共享的
含义。
“你有一个process,你需要处理一款很大的数据,你就把这个数据没成四块,然后
create四个thread,每个线程都去计算各自的数据,然后把数据汇总到进程中。这个过
程数据从进程到线程,再由线程回进程,就是一个共享的结果”
你说的共享,我理解是指在内存中同一份“很大的数据”,四个线程可以直接访问,而
不需要将各自需要处理的区块再复制到各自的私有栈中。
由你的例子引开,四个线程换成了由四台主机处理,那么每台主机都需要从“很大的数
据”中复制需要处理的区块到该主机。这样每台主机处理的是自己复制的数据,因此没
有共享这一操作。
不知道以上的理解对不对。我是ee做网络的,多线程和os比较薄弱,这段针对这一块再
补。

【在 k*****u 的大作中提到】
: share的好处就是 high performance
: 举个例子,如果你的计算机有多个core,比如说四核,那么理论上四个core可以同时进
: 行计算
: 你有一个process,你需要处理一款很大的数据,你就把这个数据没成四块,然后
: create四个thread,每个线程都去计算各自的数据,然后把数据汇总到进程中。这个过
: 程数据从进程到线程,再由线程回进程,就是一个共享的结果
: 当然share的好处不局限于此
: 如果是自己的pc也许只有四核 八核,如果是集群可能就是几十核,几百核,有很多高
: 性能的技术比如openmp(shared memory) openmpi(message passing) hadoop(
: mapreduce) 都是类似的进行计算,大同小异

z****e
发帖数: 54598
14
共享很多时候是不得不共享
如果是硬盘上的共享的话
这个比较容易解决,用db能做很多事情
还有nosql,但是这么做就比较慢,因为涉及io操作
写入硬盘,读的时候从硬盘上读,要先查一下,这些操作都很慢
有些时候,时效要求比较高
比如游戏的pvp,多个client同时联入的话,你需要在短时间内反馈给client
尤其是real time gaming,fps在30左右的话,每一个frame的间隔只有33ms
在33ms内,能做完一次跨网络的传送就不错了,如果加上硬盘的io的话
肯定完不成,所以这个时候就对共享有了较高的要求
你总不可能每一个client自己玩自己的吧?
肯定在server那边需要有一个共享数据的模型
而这个模型一般都放在内存里面
你可以先从斗地主这种游戏开始实现,然后慢慢转换成real time gaming
比如battleship对射,real time的那种
这个时候你就知道多线程和共享几乎是绕不开的
一般的web搞这些也不是完全不可以,但是太吃资源了
g*********e
发帖数: 14401
15
我说这里的thread obj在heap上
int 在thread里

【在 z****e 的大作中提到】
: 共享很多时候是不得不共享
: 如果是硬盘上的共享的话
: 这个比较容易解决,用db能做很多事情
: 还有nosql,但是这么做就比较慢,因为涉及io操作
: 写入硬盘,读的时候从硬盘上读,要先查一下,这些操作都很慢
: 有些时候,时效要求比较高
: 比如游戏的pvp,多个client同时联入的话,你需要在短时间内反馈给client
: 尤其是real time gaming,fps在30左右的话,每一个frame的间隔只有33ms
: 在33ms内,能做完一次跨网络的传送就不错了,如果加上硬盘的io的话
: 肯定完不成,所以这个时候就对共享有了较高的要求

k****i
发帖数: 101
16
public class Main {
static java.util.List list = new java.util.ArrayList<>();
static synchronized void safeAdd() {
unsafeAdd();
}
static void unsafeAdd() {
for(int i = 0; i < 1000000; ++ i) {
list.add(i);
};
}
static void go(Thread t1, Thread t2) throws Exception {
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(list.size());
}
public static void main(String[] args) throws Exception {
go(new Thread(() -> safeAdd()), new Thread(() -> safeAdd()));
list.clear();
go(new Thread(() -> unsafeAdd()), new Thread(() -> unsafeAdd()));
}
}

【在 d*********g 的大作中提到】
: 最近看java多线程郁闷了,理解不了线程之间共享进程地址空间。
: 举个栗子:
: class M extends Thread{
: int mValue=0;
: public void run(){...}
: }
: class N extends Thread{
: int nValue=1;
: public void run{...}
: }

D**C
发帖数: 6754
17
1 不是共享,你开了两个thread,每个thread都有自己的stack,thread里面的local
val 是primtive在stack上。
2 是在main的stack上
你这个例子不好,因为变量都是primative,需要是object才有意义。

【在 d*********g 的大作中提到】
: 最近看java多线程郁闷了,理解不了线程之间共享进程地址空间。
: 举个栗子:
: class M extends Thread{
: int mValue=0;
: public void run(){...}
: }
: class N extends Thread{
: int nValue=1;
: public void run{...}
: }

s***a
发帖数: 82
18


【在 d*********g 的大作中提到】
: 的确是半路出家,刚开始看多线程,一团雾水,感谢楼上几位。
: 那很多资料都写到“All threads of a process share its virtual address space
: and system resources.”或类似的意思,这个share有什么好处呢,既然每个线程都有
: 自己的私有栈。

s***a
发帖数: 82
19
首先搞清楚什么是虚拟地址空间。
share的好处是协同工作。 比如交易记录要写到共享的数据表里, 如果只是在自己的
stack里做,
别人看不到有啥用呢。

【在 d*********g 的大作中提到】
: 的确是半路出家,刚开始看多线程,一团雾水,感谢楼上几位。
: 那很多资料都写到“All threads of a process share its virtual address space
: and system resources.”或类似的意思,这个share有什么好处呢,既然每个线程都有
: 自己的私有栈。

k*****u
发帖数: 136
20
首先,楼主你如果真想转cs 要看操作系统,数据结构与算法,这两个是最最基本的,
如果还能看看计算机体系结构就更好了。楼主的问题如下,
你说的共享,我理解是指在内存中同一份“很大的数据”,四个线程可以直接访问,而
不需要将各自需要处理的区块再复制到各自的私有栈中。
--> 我没有说过copy,可以直接访问,也可以copy过去,现实中为了防止子线程搞乱主
进程的数据,一般是通过一个函数或者方法读取一块特定的数据,当然理论上你可以直
接访问,这就是为什么说线程是共享资源的
说到这里,你应该听过进程之间的独立资源的。
由你的例子引开,四个线程换成了由四台主机处理,那么每台主机都需要从“很大的数
据”中复制需要处理的区块到该主机。这样每台主机处理的是自己复制的数据,因此没
有共享这一操作。
--> 如果变成四个主机(我当时说道的集群只是举例,大规模数据是怎么被分配处理的
)如果变成四个主机,就是四个独立系统了,这时候进程 线程的都是各自系统的,已
经没有什么共享不共享一说。完全就不是一回事。多线程就指在一个系统中。
如果有时间的话,可以到网上听听online的cs课程
相关主题
Python 多线程或多进程如何搞怎么 kill 一个 thread 啊
重复利用threads的问题[合集] 为什么多个线程生成的随机数是一样的?
Thread Priority 设为最高--窗口最小化时好像并不优先啊?多线程有什么优化的方法?
进入Programming版参与讨论
d*********g
发帖数: 38
21
感谢keiutou详细而耐心的介绍,真好人也。
操作系统还是躲不掉啊。。。-_-!!!

【在 k*****u 的大作中提到】
: 首先,楼主你如果真想转cs 要看操作系统,数据结构与算法,这两个是最最基本的,
: 如果还能看看计算机体系结构就更好了。楼主的问题如下,
: 你说的共享,我理解是指在内存中同一份“很大的数据”,四个线程可以直接访问,而
: 不需要将各自需要处理的区块再复制到各自的私有栈中。
: --> 我没有说过copy,可以直接访问,也可以copy过去,现实中为了防止子线程搞乱主
: 进程的数据,一般是通过一个函数或者方法读取一块特定的数据,当然理论上你可以直
: 接访问,这就是为什么说线程是共享资源的
: 说到这里,你应该听过进程之间的独立资源的。
: 由你的例子引开,四个线程换成了由四台主机处理,那么每台主机都需要从“很大的数
: 据”中复制需要处理的区块到该主机。这样每台主机处理的是自己复制的数据,因此没

z****e
发帖数: 54598
22
楼主目测没有搞懂什么是thread
先理解一下thread
这个跟os没啥关系,虽然java的thread只是os的一层wrapper
但是不懂os也没有什么关系
java所有的program,在启动的时候,会马上启动一个thread
至少一个,这个就是main thread,就是你的main运行的thread
然后其他的thread,如果你启动的话,就会再启动threads
你可以用thread dump看一下你的程序到底运行了多少个threads
然后每个thread有自己的stack,heap部分是共用的
楼主还是要理解java对象以及primitive type两个内存中存放方式的不同
感觉这些跟os没太大关系,虽然os每个人都上过
但是时间一久,不用早就还给老师了
我知道的文科生不懂os一样学java学得好好的
java的多线程是comp101的东西,不用搞那么复杂
z****e
发帖数: 54598
23
一个program理论上就只有一个process
尤其是可以开多个threads的program
一个process可以运行多个threads
然后每一个thread有自己的stack
但是object并不仅仅是放在stack中
object有两个部分,主体存放在heap里面
然后heap里面的地址,放在stack中
这就是java中的reference
每个thread保留的是object的reference
每次访问的时候,取出reference然后再去heap中把数据读出来
但是有例外,primitive type,比如int, char, boolean这些数据
是直接存放在stack上的,而不是存地址/引用
所以每次用int的时候,不需要访问heap
比如下图中的alphabet,就直接放在stack上了
这就是为啥别人说这个例子看不出来的缘故
你需要object,只有object可以被共享,如果不是object的话
每个thread用到的primitive type都是自己stack上的
楼主是java没学好,不是os的问题
java认认真真从reference, heap, stack这些开始学
到这里应该不是问题,heap, stack这是初学java时候就开始学的
目测楼主没经过这一步,老用ee那一套来思考,那就相当于从怎么造jvm开始搞
那这样一来,你这个路就走错了,jvm很难,而且也没有必要
忘掉你的ee吧,从java基础概念开始搞,否则java会变得很困难
这也是为什么很多ee转行的学得反而不如生物转行的原因
因为生物转行的不会用这一套底层的思维去思考问题
一张白纸,反而容易写,ee转行的老要解释很多底层的东西
那jvm又不是每个人都造过,很多东西就很难解释清楚
c*********e
发帖数: 16335
24
那volatile boolean呢,为什么就能每个thread都能看到?每次一个thread里的
volatile boolean变量的值变了,其它所有的thread的这个变量的值也跟着变吗?怎么
保证volatile变量的可见性的呢?

【在 z****e 的大作中提到】
: 一个program理论上就只有一个process
: 尤其是可以开多个threads的program
: 一个process可以运行多个threads
: 然后每一个thread有自己的stack
: 但是object并不仅仅是放在stack中
: object有两个部分,主体存放在heap里面
: 然后heap里面的地址,放在stack中
: 这就是java中的reference
: 每个thread保留的是object的reference
: 每次访问的时候,取出reference然后再去heap中把数据读出来

z****e
发帖数: 54598
25

volatile是强制每次都去取一次value,对于所有thread都可见
如果你知道怎么造jvm的话,你就放心地用
如果不知道的话,就老老实实用synchronized关键字
或者干脆就用java.util, spring, vert.x那些
表没事找事,volatile很早以前就不被推荐使用了

【在 c*********e 的大作中提到】
: 那volatile boolean呢,为什么就能每个thread都能看到?每次一个thread里的
: volatile boolean变量的值变了,其它所有的thread的这个变量的值也跟着变吗?怎么
: 保证volatile变量的可见性的呢?

c*********e
发帖数: 16335
26
瞎说,volatile还是有用的,关键是看你怎么用。

【在 z****e 的大作中提到】
:
: volatile是强制每次都去取一次value,对于所有thread都可见
: 如果你知道怎么造jvm的话,你就放心地用
: 如果不知道的话,就老老实实用synchronized关键字
: 或者干脆就用java.util, spring, vert.x那些
: 表没事找事,volatile很早以前就不被推荐使用了

z****e
发帖数: 54598
27

在任何时候,volatile都可以不用,就像你自己手写thread一样
早就没人这么用了,你自己跟不上时代就别说别人瞎说

【在 c*********e 的大作中提到】
: 瞎说,volatile还是有用的,关键是看你怎么用。
c*********e
发帖数: 16335
28
你把自己的跟上时代的java multi-threading code贴出来让大家看看。

【在 z****e 的大作中提到】
:
: 在任何时候,volatile都可以不用,就像你自己手写thread一样
: 早就没人这么用了,你自己跟不上时代就别说别人瞎说

z****e
发帖数: 54598
29

util.concurrent, spring,vert.x都是对付多线程的,说了几万遍了,你不听谁有办法
你能不能不要再让我重复这些说过的话,很烦诶

【在 c*********e 的大作中提到】
: 你把自己的跟上时代的java multi-threading code贴出来让大家看看。
c*********e
发帖数: 16335
30
vert.x在袋鼠国非常流行吗?

办法

【在 z****e 的大作中提到】
:
: util.concurrent, spring,vert.x都是对付多线程的,说了几万遍了,你不听谁有办法
: 你能不能不要再让我重复这些说过的话,很烦诶

相关主题
请教一个linux下面的多线程semaphore的问题。关于thread的stack
请教一个线程同步的问题。问个线程同步的问题
Java的服务器一般运行几个线程比较合适?求C/C++面试题
进入Programming版参与讨论
z****e
发帖数: 54598
31

说了很多遍了,你不识货
我要是告诉你这个东西在欧洲很流行
你是不是就觉得高大上了起来?

【在 c*********e 的大作中提到】
: vert.x在袋鼠国非常流行吗?
:
: 办法

1 (共1页)
进入Programming版参与讨论
相关主题
[合集] 为什么多个线程生成的随机数是一样的?问个C++编译器如何处理函数内的static 变量
多线程有什么优化的方法?question about volatile variable on multiple cores
请教一个linux下面的多线程semaphore的问题。关于线程读写全局变量的问题
请教一个线程同步的问题。win 7 pro 正常情况多少进程/线程?
Java的服务器一般运行几个线程比较合适?大量读HBase的任务该加线程还是进程?
关于thread的stack用volatile退出线程对不对?(C++)
问个线程同步的问题Bihai,你就用atmoic完事了
求C/C++面试题Python 多线程或多进程如何搞
相关话题的讨论汇总
话题: thread话题: 共享话题: 线程话题: main话题: 进程