黑马程序员技术交流社区
标题: 关于线程、同步、锁的一个问题 [打印本页]
作者: 匡文 时间: 2013-10-21 17:11
标题: 关于线程、同步、锁的一个问题
本帖最后由 匡文 于 2013-10-21 17:44 编辑
是毕老师视频中讲解线程的一个例子,我按着他的思路敲的代码,同步的语句加了锁(obj),但是仍然没能同步- class Bank{
- private int sum;
- public void add(int i){
- Object obj = new Object();
- synchronized (obj){
- sum = sum + i;
- try{
- Thread.sleep(100);
- }catch(Exception e){
- }
- System.out.println(Thread.currentThread().getName()+"sum= " + sum);
- }
- }
- }
- class Cus implements Runnable{
- private Bank b = new Bank();
- public void run(){
- for(int i=0;i<3;i++){
- b.add(100);
- }
- }
- }
- class TestBank{
- public static void main(String[] args){
- Cus c = new Cus();
-
- Thread t1 = new Thread(c);
- Thread t2 = new Thread(c);
- t1.start();
- t2.start();
- }
- }
复制代码 按理说加了锁之后,无论运行多少次,输出结果都应该是
Thread-0sum= 100
Thread-1sum= 200
Thread-0sum= 400
Thread-1sum= 500
Thread-0sum= 600
Thread-1sum= 600
但是,上面代码输出结果偶尔仍然是:
Thread-0sum= 200
Thread-1sum= 200
Thread-0sum= 400
Thread-1sum= 500
Thread-0sum= 600
Thread-1sum= 600
“200”出现了2次,“100”没有出现,说明还是存在线程安全问题。。。但是我已经加锁了的呀,这是为什么?
作者: kellyzyb 时间: 2013-10-21 17:23
- class Bank{
- private int sum;
- public synchronized void add(int i)
- {
- sum = sum + i;
- try
- {
- Thread.sleep(100);
- System.out.println(Thread.currentThread().getName()+"sum= " + sum);
- }catch(Exception e)
- {
-
- }
-
- }
- }
- class Cus implements Runnable{
- private Bank b = new Bank();
- public void run(){
- for(int i=0;i<3;i++){
- b.add(100);
- }
- }
- }
- class TestBank{
- public static void main(String[] args){
- Cus c = new Cus();
-
- Thread t1 = new Thread(c);
- Thread t2 = new Thread(c);
- t1.start();
- t2.start();
- }
- }
复制代码
作者: 匡文 时间: 2013-10-21 17:26
你这是改成同步函数了,也行。。。但是我想知道,我那样同步代码块为什么会错。。。
作者: kellyzyb 时间: 2013-10-21 17:30
上面是我改的代码,针对你的代码的话,问题:要保证锁的唯一性。 b.add(100);这个方法每个线程去访问这个add这个方法,都会创建一个Object 。持有两把锁怎么能安全呢?下面是我改的原代码。- class Bank{
- private int sum;
- Object obj = new Object();
- public void add(int i){
-
- synchronized (obj)
- {
- sum = sum + i;
- try
- {
- Thread.sleep(100);
- System.out.println(Thread.currentThread().getName()+"sum= " + sum);
- }catch(Exception e)
- {
-
- }
-
- }
- }
- }
- class Cus implements Runnable{
- private Bank b = new Bank();
- public void run(){
- for(int i=0;i<3;i++){
- b.add(100);
- }
- }
- }
- class TestBank{
- public static void main(String[] args){
- Cus c = new Cus();
-
- Thread t1 = new Thread(c);
- Thread t2 = new Thread(c);
- t1.start();
- t2.start();
- }
- }
复制代码
作者: 黑马-马磊 时间: 2013-10-21 17:40
本帖最后由 黑马-马磊 于 2013-10-21 17:44 编辑
Object obj = new Object();
定义的位置不对!
我的找出问题的步骤:
确定是2个或者2歌以上的线程参与运行,那么只能是锁出现了问题(是不是同一把锁)。按照你的写法是每次都用都会创建一个锁,不是唯一的。要把锁提出来!
希望遇到类似的问题能够参加毕老师总结的方法解决问题
作者: 匡文 时间: 2013-10-21 17:43
哦。。。。明白了,每个线程都会创建一次,我锁定义错地方了:o,谢谢
作者: 匡文 时间: 2013-10-21 17:43
嗯,谢谢提醒
作者: 马晓平 时间: 2013-10-21 23:08
你写错了吧,首先你Object obj = new Object();这句都写错位置了吧
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |