论坛首页 综合技术论坛

多线程开发,表示很凌乱

浏览 12474 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-04-17  
junlas 写道

 

第一次做网络应用的一个项目的服务器端,以前一直都是ssh开发,tomcat服务器,也做过很长时间的客户端从没考虑过多线程的问题,现在不做web项目、也不纯客户端开发了,忽然觉得头大。

 

说说主要困惑,举个例子来说,我总是会想到这个类实例化以后的这个对象,在同一时间可能会被N多客户端请求,那么我担心这种并发会导致我当前对象中的数据交错,一不是一,二也不是二了,所以,有种恨不得每个方法都是synchronized的,但是很明显这样做,是不对的。当然,以前也学习过多线程的基础,网上的资料也没少看、少找,但是还是不能完全切透这种模式的思路。

楼主还没有理解“线程安全”的含义,线程本身不存在什么安全不安全的问题,主要体现在一个线程在执行某个方法时,对这个类内部的属性变量访问的安全与否。拿servlet来说,为什么说他不安全,是指在servlet中对定义的类变量访问不安全。

 

所以楼主只要理解了这句话,就会明白,只有可修改的类变量才有线程安全问题(如只读的常量也不存在线程安全问题),对于方法中传入的参数或其他声明的临时变量,根本不存在线程安全问题。

 

类变量线程安全又分2种情况,

第一种是单例,如果一个类的实例是单例的,所有线程都访问相同的实例,那么这个类的类变量不是线程安全的,因为一个线程对这个实例的类变量任何操作,都会影响到其他线程。

第二种是多例,如果在不同线程方法中,创建了对象,那么这2个对象由各自线程管理,互不干扰,也不存在线程安全问题。

 

0 请登录后投票
   发表时间:2012-04-17  
spyker 写道
去看一本书
Java并发编程实践



好的,这本书我这周就去买来
0 请登录后投票
   发表时间:2012-04-17   最后修改:2012-04-17
zfc827 写道
junlas 写道

 

第一次做网络应用的一个项目的服务器端,以前一直都是ssh开发,tomcat服务器,也做过很长时间的客户端从没考虑过多线程的问题,现在不做web项目、也不纯客户端开发了,忽然觉得头大。

 

说说主要困惑,举个例子来说,我总是会想到这个类实例化以后的这个对象,在同一时间可能会被N多客户端请求,那么我担心这种并发会导致我当前对象中的数据交错,一不是一,二也不是二了,所以,有种恨不得每个方法都是synchronized的,但是很明显这样做,是不对的。当然,以前也学习过多线程的基础,网上的资料也没少看、少找,但是还是不能完全切透这种模式的思路。

楼主还没有理解“线程安全”的含义,线程本身不存在什么安全不安全的问题,主要体现在一个线程在执行某个方法时,对这个类内部的属性变量访问的安全与否。拿servlet来说,为什么说他不安全,是指在servlet中对定义的类变量访问不安全。

 

所以楼主只要理解了这句话,就会明白,只有可修改的类变量才有线程安全问题(如只读的常量也不存在线程安全问题),对于方法中传入的参数或其他声明的临时变量,根本不存在线程安全问题。

 

类变量线程安全又分2种情况,

第一种是单例,如果一个类的实例是单例的,所有线程都访问相同的实例,那么这个类的类变量不是线程安全的,因为一个线程对这个实例的类变量任何操作,都会影响到其他线程。

第二种是多例,如果在不同线程方法中,创建了对象,那么这2个对象由各自线程管理,互不干扰,也不存在线程安全问题。

 

 

 

 

 

嗯,非常感谢回复这么多,还是可以理解的。我把我的一个疑惑描述一下,可能有点2。有一种这样的情况,唯一的一个共享数据对象O,内部有方法A,方法B,起了5个线程去执行方法A,起了另外3个线程执行方法B,好的,请教,在方法A、B中:

1.访问对象O中的普通类变量需要synchronized,如果不是普通类变量,是java.util.concurrent包下的类型变量,就不用synchronized了,这点没错吧,如果没错,我理解的应该就没错。正如你上面所说。

2.方法A、B中的参数、临时变量,是否也需要synchronized?这是比较疑惑的了,我发帖的主要原因。我的理解是:线程1可能正执行到方法A、B的一半时,被切到线程2来执行这个方法,因为参数和临时变量没synchronized,这个值就变了??

 

我觉得是我肯定理解错了?求指点,如何理解呢

0 请登录后投票
   发表时间:2012-04-17  
2.方法A、B中的参数、临时变量,是否也需要synchronized?

看来你对线程的理解还没入门。每个线程都有自己的线程栈,方法传入参数、临时变量都会在线程栈中,线程切换过程,线程栈也会随着切换
0 请登录后投票
   发表时间:2012-04-17  
[quote="junlas"]
[quote="zfc827"]
[quote="junlas"]

第一次做网络应用的一个项目的服务器端,以前一直都是ssh开发,tomcat服务器,也做过很长时间的客户端从没考虑过多线程的问题,现在不做web项目、也不纯客户端开发了,忽然觉得头大。


说说主要困惑,举个例子来说,我总是会想到这个类实例化以后的这个对象,在同一时间可能会被N多客户端请求,那么我担心这种并发会导致我当前对象中的数据交错,一不是一,二也不是二了,所以,有种恨不得每个方法都是synchronized的,但是很明显这样做,是不对的。当然,以前也学习过多线程的基础,网上的资料也没少看、少找,但是还是不能完全切透这种模式的思路。


楼主还没有理解“线程安全”的含义,线程本身不存在什么安全不安全的问题,主要体现在一个线程在执行某个方法时,对这个类内部的属性变量访问的安全与否。拿servlet来说,为什么说他不安全,是指在servlet中对定义的类变量访问不安全。


所以楼主只要理解了这句话,就会明白,只有可修改的类变量才有线程安全问题(如只读的常量也不存在线程安全问题),对于方法中传入的参数或其他声明的临时变量,根本不存在线程安全问题。


类变量线程安全又分2种情况,

第一种是单例,如果一个类的实例是单例的,所有线程都访问相同的实例,那么这个类的类变量不是线程安全的,因为一个线程对这个实例的类变量任何操作,都会影响到其他线程。

第二种是多例,如果在不同线程方法中,创建了对象,那么这2个对象由各自线程管理,互不干扰,也不存在线程安全问题。







嗯,非常感谢回复这么多,还是可以理解的。我把我的一个疑惑描述一下,可能有点2。有一种这样的情况,唯一的一个共享数据对象O,内部有方法A,方法B,起了5个线程去执行方法A,起了另外3个线程执行方法B,好的,请教,在方法A、B中:

1.访问对象O中的普通类变量需要synchronized,如果不是普通类变量,是java.util.concurrent包下的类型变量,就不用synchronized了,这点没错吧,如果没错,我理解的应该就没错。正如你上面所说。

2.方法A、B中的参数、临时变量,是否也需要synchronized?这是比较疑惑的了,我发帖的主要原因。我的理解是:线程1可能正执行到方法A、B的一半时,被切到线程2来执行这个方法,因为参数和临时变量没synchronized,这个值就变了??


我觉得是我肯定理解错了?求指点,如何理解呢





方法中的临时变量不是多线程共享的,因此不需要同步,这是每个方法私有的。说道参数,要看这个参数是不是对象,是对象的话,这个对象有没有被多个线程共享,如果共享了,那就要同步住这个对象所涉及的所有方法:sychronized(对象)。
说白了,无非一句话,被共享的变量被多个线程改变时,就要同步。
0 请登录后投票
   发表时间:2012-04-18  
有2个方法操纵一个map对象,怎么实现线程安全?
2个方法都加上锁?
0 请登录后投票
   发表时间:2012-04-18  
schweigen 写道
2.方法A、B中的参数、临时变量,是否也需要synchronized?

看来你对线程的理解还没入门。每个线程都有自己的线程栈,方法传入参数、临时变量都会在线程栈中,线程切换过程,线程栈也会随着切换



   受益良多啊。谢谢。
0 请登录后投票
   发表时间:2012-04-18  
837062099 写道
[quote="junlas"]
[quote="zfc827"]
[quote="junlas"]

第一次做网络应用的一个项目的服务器端,以前一直都是ssh开发,tomcat服务器,也做过很长时间的客户端从没考虑过多线程的问题,现在不做web项目、也不纯客户端开发了,忽然觉得头大。


说说主要困惑,举个例子来说,我总是会想到这个类实例化以后的这个对象,在同一时间可能会被N多客户端请求,那么我担心这种并发会导致我当前对象中的数据交错,一不是一,二也不是二了,所以,有种恨不得每个方法都是synchronized的,但是很明显这样做,是不对的。当然,以前也学习过多线程的基础,网上的资料也没少看、少找,但是还是不能完全切透这种模式的思路。


楼主还没有理解“线程安全”的含义,线程本身不存在什么安全不安全的问题,主要体现在一个线程在执行某个方法时,对这个类内部的属性变量访问的安全与否。拿servlet来说,为什么说他不安全,是指在servlet中对定义的类变量访问不安全。


所以楼主只要理解了这句话,就会明白,只有可修改的类变量才有线程安全问题(如只读的常量也不存在线程安全问题),对于方法中传入的参数或其他声明的临时变量,根本不存在线程安全问题。


类变量线程安全又分2种情况,

第一种是单例,如果一个类的实例是单例的,所有线程都访问相同的实例,那么这个类的类变量不是线程安全的,因为一个线程对这个实例的类变量任何操作,都会影响到其他线程。

第二种是多例,如果在不同线程方法中,创建了对象,那么这2个对象由各自线程管理,互不干扰,也不存在线程安全问题。







嗯,非常感谢回复这么多,还是可以理解的。我把我的一个疑惑描述一下,可能有点2。有一种这样的情况,唯一的一个共享数据对象O,内部有方法A,方法B,起了5个线程去执行方法A,起了另外3个线程执行方法B,好的,请教,在方法A、B中:

1.访问对象O中的普通类变量需要synchronized,如果不是普通类变量,是java.util.concurrent包下的类型变量,就不用synchronized了,这点没错吧,如果没错,我理解的应该就没错。正如你上面所说。

2.方法A、B中的参数、临时变量,是否也需要synchronized?这是比较疑惑的了,我发帖的主要原因。我的理解是:线程1可能正执行到方法A、B的一半时,被切到线程2来执行这个方法,因为参数和临时变量没synchronized,这个值就变了??


我觉得是我肯定理解错了?求指点,如何理解呢





方法中的临时变量不是多线程共享的,因此不需要同步,这是每个方法私有的。说道参数,要看这个参数是不是对象,是对象的话,这个对象有没有被多个线程共享,如果共享了,那就要同步住这个对象所涉及的所有方法:sychronized(对象)。
说白了,无非一句话,被共享的变量被多个线程改变时,就要同步。




    了解。。
0 请登录后投票
   发表时间:2012-04-18  
aa87963014 写道
有2个方法操纵一个map对象,怎么实现线程安全?
2个方法都加上锁?



一般我都是用ConcurentHashMap这个对象
0 请登录后投票
   发表时间:2012-04-18  
队列,LZ你只要深刻理解掌握队列,那么写多线程的话就绰绰有余了。
只要结构设计得合理,把操作都序列成action,那么很多地方都不必加锁。
举个例子,比如A和B都同时访问某个数据,那么你只要把A和B的请求都封装成action,丢进队列里,那么,数据根本不必加锁,队列加锁就行。说到底这就是异步的思想。
抛开多核cpu不讲,就以前的单核,其实线程也只不过是分片执行的模拟而已。在系统内核,阻塞其实就是CPU空转,所以无论你怎么模拟同步,最终还是单个“线程”在跑而已。所以异步架构更适合现在PC架构,即便现在多核CPU,采用异步也能大大减少锁带来的热点。
从我们大多数应用场景来看,CPU并不是瓶颈,IO才是。所以我很推崇NODEJS的那一套,简洁明了。
0 请登录后投票
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics