A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 linweiwen 于 2014-3-30 17:01 编辑
  1. package com.itheima;

  2. /*
  3. * 四个窗口同时卖1000张票。
  4. * */
  5. public class sellTicket {
  6.         public static void main(String args[]) {
  7.                 myTicket t = new myTicket();
  8.                 Thread Mt1 = new Thread(t);
  9.                 Thread Mt2 = new Thread(t);
  10.                 Thread Mt3 = new Thread(t);
  11.                 Thread Mt4 = new Thread(t);
  12.                 Mt1.start();
  13.                 Mt2.start();
  14.                 Mt3.start();
  15.                 Mt4.start();
  16.         }
  17. }

  18. class myTicket implements Runnable {

  19.         private static int ticket = 100;

  20.         Object obj = new Object();
  21.         @Override
  22.         public void run() {
  23.                 synchronized (obj) {
  24.                         while (ticket > 0) {
  25.                        
  26.                                 try {
  27.                                         Thread.sleep(2);
  28.                                         System.out.println(Thread.currentThread().getName() + " : "
  29.                                                         + ticket--);
  30.                                 } catch (InterruptedException e) {
  31.                                         e.printStackTrace();
  32.                                 }
  33.                         }
  34.                 }
  35.         }
  36. }
复制代码



首先,上面代码是正常的情况。
然后我想问两个问题:
1.为什么我把while的循环条件剔除在同步代码块外面,就会出现结果不安全的问题。
  1. while (ticket > 0) {
  2.                                 synchronized (obj) {
  3.                                 try {
复制代码
while (ticket > 0)也算是操作共享数据的语句?
大家一般怎么判断同步代码块的范围的?视频教程里面的不够具体啊。

2.为什么synchronzied()中直接生产一个Object传进去,而不是传一个已经new出来的对象,
就会出现问题?
  1. synchronized (new Object()) {
  2.                         while (ticket > 0) {……
  3.                         
复制代码
不是传入一个对象就OK 了吗?

请各位帮忙解答一下,谢谢:)


评分

参与人数 1技术分 +1 收起 理由
枫儿 + 1 神马都是浮云

查看全部评分

6 个回复

倒序浏览
如果你传入匿名对象,那么两个同步函数 永远不是一个锁啊

要保证两个同步函数 传入的对象是同一个即可
回复 使用道具 举报
因为new出来的不是同一个锁对象,是但不要互斥的效果的,如果要互斥,必须要先有锁,而且要保证锁是同一个对象
回复 使用道具 举报
osully 发表于 2014-3-30 16:43
如果你传入匿名对象,那么两个同步函数 永远不是一个锁啊

要保证两个同步函数 传入的对象是同一个即可 ...

你们效率实在太高了,
我贴漏了开始的代码,你们也不到1分钟就回答了。
我指的是同步代码块,不是同步函数。
看了你们的回答,
我的理解是
Object obj  = newObject(); //先生成一个对象
synchronized(obj){……    //再根据这个对象生成的锁,才是在同一个锁里?
}
回复 使用道具 举报
黄晓鑫 发表于 2014-3-30 16:45
因为new出来的不是同一个锁对象,是但不要互斥的效果的,如果要互斥,必须要先有锁,而且要保证锁是同一个 ...

我知道怎么回事了,
另外想请问一下,synchronized是不是API里没有的?
找来找去没找到。
回复 使用道具 举报
闲的蛋疼,就刷刷贴帮你们一下咯....手快...是的同步代码块传入的对象是同一个即可

synchonized 只是一个关键字.关键字是没有的
回复 使用道具 举报
osully 发表于 2014-3-30 17:13
闲的蛋疼,就刷刷贴帮你们一下咯....手快...是的同步代码块传入的对象是同一个即可

synchonized 只是一个关 ...

噢,我知道它是一个关键字,
但习惯了不知道的先去API文档看一下,
被你提醒一下才发现这个情况。谢谢了!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马