阅读《java并发编程实战》,有一个地方有疑惑,求解答 并发 多线程 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 我想作者的意思应该是,因为list本身是public的,所以你在这个方法上对类加锁而不对list加锁,那么这个对象还是可以被别的线程所操作。强调的一点是,所有的锁要加在同一个对象上,比如你要操作list,那么就都对list加锁,这样就可以保证安全了。当然这个例子里还有其他的线程安全问题,我这里说的保证安全是保证不被多个线程同时操作 如果 list 成员是公有的,则无法保证真正锁,因为调用者可以直接得到 list 的引用,然后改变它内部元素synchronized 并不能保证一段语句是原子操作,而是保证进入语句块之前,必须要先得到锁,如果得不到锁就必须等待别的线程释放锁 因为4-15使用的是对象内置锁,即锁住了list集合了又因为对象内置锁是互相排斥的所以当一个线程操作list的时候其他线程就不能操作list了4-14是的锁是加载方法上的,这个锁对于这个方法来说是同步的,其他线程不可以访问这个方法但是假如这个对象ListHelper 内还有其他普通方法(这些普通方法没有加锁) 这些方法也对list进行了增删,而其他线程恰好执行这些方法时 那么相对于list来说他就不是同步的了(因为list它本身就没有上对象内置锁 ,不会出现互斥) 请问是不是同步代码块有两层语义,比如在同步代码块synchronized(list){}中,1.同一时刻只有一个线程可以执行里面的代码2.某个线程执行里面的代码时,其他线程无法修改list 请问是不是同步代码块有两层语义,比如在同步代码块synchronized(list){}中,1.同一时刻只有一个线程可以执行里面的代码2.某个线程执行里面的代码时,其他线程无法修改list你不要这样理解锁,你要把锁理解为一种信号,一次性只能有一个线程获取,所以:1. 同一个时刻同一把锁只能由一个线程获取,所以被锁住的部分只能一个线程执行2. 如同我的分析,如果所有的线程都尝试去对 list加锁,那么同一个时刻必然只有一个线程可以获取到list上的锁,从而可以做相关的操作 锁是用来保护某个对象的,锁加在方法上,保护的是当前对象this,实际上锁应该保护list集合,所以应该加在list上。 第一个是方法锁,保证方法的线程安全,但是此时list可能被其他方法进行增删查改,就导致list内容乱掉,就没有任何安全的意义了。第二个是对象锁,保证list是线程安全,虽然此方法可以被多个线程同时访问,但是list对象只能允许一个线程去做修改 。 2楼讲得有道理。这个问题应该把ListHelper想成一个单例singleton的环境中,多个线程访问它。“如果有10个ListHelper对象",每线程一个,就都是线程安全的,没考虑的必要了,因为ListHelper.list成员又不是static.4-14不安全的反例:/*线程1*/boolean absent = !list.contains("X");// 此时发生时间片轮转,假如转到线程2执行Thread.sleep(100);if(absent) list.add("X");/*线程2*/var list = listHelper.list;list.add("X");//结果list中两个"X".这个例子总结起来就一句话:要使用相同的锁。你这话是对的。 两时间相减 得出一个long,怎么再转回到Date(yy-MM-dd hh-mm-ss) 在组合框上鼠标右击弹出菜单 PROPERTIES 文件如何加入工程里? 函数问题 VB程序员转JAVA需要注意些什么或重点是什么?请高手指点。 thinking in java 中的一端代码有不明白的地方 菜鸟求教!谢了,谢了! applet invoke dll 有关jtable的问题。请指教。 crystal report 做好的报表在jbuilder5里面使用的问题。 Quartz的定时执行 刚接触java,一个模拟多线程的聊天程序,不知道注释掉的代码为什么删掉程序正常运行,保留程序出错...
又因为对象内置锁是互相排斥的
所以当一个线程操作list的时候
其他线程就不能操作list了
4-14是的锁是加载方法上的,这个锁对于这个方法来说是同步的,其他线程不可以访问这个方法
但是假如这个对象ListHelper 内还有其他普通方法(这些普通方法没有加锁) 这些方法也对list进行了增删,
而其他线程恰好执行这些方法时 那么相对于list来说他就不是同步的了
(因为list它本身就没有上对象内置锁 ,不会出现互斥)
1.同一时刻只有一个线程可以执行里面的代码
2.某个线程执行里面的代码时,其他线程无法修改list
1.同一时刻只有一个线程可以执行里面的代码
2.某个线程执行里面的代码时,其他线程无法修改list你不要这样理解锁,你要把锁理解为一种信号,一次性只能有一个线程获取,所以:
1. 同一个时刻同一把锁只能由一个线程获取,所以被锁住的部分只能一个线程执行
2. 如同我的分析,如果所有的线程都尝试去对 list加锁,那么同一个时刻必然只有一个线程可以获取到list上的锁,从而可以做相关的操作
第二个是对象锁,保证list是线程安全,虽然此方法可以被多个线程同时访问,但是list对象只能允许一个线程去做修改 。
这个问题应该把ListHelper想成一个单例singleton的环境中,多个线程访问它。“如果有10个ListHelper对象",每线程一个,就都是线程安全的,没考虑的必要了,因为ListHelper.list成员又不是static.
4-14不安全的反例:/*线程1*/
boolean absent = !list.contains("X");
// 此时发生时间片轮转,假如转到线程2执行
Thread.sleep(100);
if(absent) list.add("X");/*线程2*/
var list = listHelper.list;
list.add("X");
//结果list中两个"X".这个例子总结起来就一句话:要使用相同的锁。你这话是对的。