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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 李志敏 中级黑马   /  2013-4-21 22:42  /  1941 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 李志敏 于 2013-4-21 23:06 编辑

毕老师11天10视频中的代码
  1. class Ticket implements Runnable{
  2.         private int tic=100;
  3.         
  4.         public void run(){
  5.                 while(true){
  6.                         synchronized (new Object()) {
  7.                                 if(tic>0){
  8.                                         try {
  9.                                                 Thread.sleep(10);//出现-1、-2号票 有安全问题
  10.                                         } catch (InterruptedException e) {
  11.                                                 e.printStackTrace();
  12.                                         }
  13.                                         System.out.println(Thread.currentThread().getName()+"ticket"+tic--);
  14.                                 }
  15.                         }
  16.                 }
  17.         }
  18. }
  19. public class TicketDemo {
  20.         public static void main(String[] args) {

  21.                 Ticket t=new Ticket();
  22.                 Thread t1=new Thread(t);
  23.                 Thread t2=new Thread(t);
  24.                 Thread t3=new Thread(t);
  25.                 Thread t4=new Thread(t);
  26.                 t1.start();
  27.                 t2.start();
  28.                 t3.start();
  29.                 t4.start();
  30.                
  31.         }
  32. }
复制代码
输出结果依然有-1,-2号的票  这是怎么回事?

评分

参与人数 1技术分 +1 收起 理由
张熙韬 + 1

查看全部评分

5 个回复

倒序浏览
本帖最后由 杨玄文 于 2013-4-21 22:51 编辑

你的锁有问题。
建议把锁定义在外面。
Object obj = new Object();
然后用obj当锁。

你这样子每次循环都会新new出一个锁来。所以是锁不住的。
回复 使用道具 举报
问题出在 synchronized (new Object()) 这里 ,每次都会new出一个新的对象,即使用的不是同一把锁。应该是
class Ticket implements Runnable{
        ......
        ......
        private Object obj = new Object();
        public void run(){
                while(true){
                        synchronized (obj) {//确保每次使用的都是同一把锁
                        .....
                        .....
                        .....
回复 使用道具 举报
本帖最后由 李志敏 于 2013-4-21 23:05 编辑
杨玄文 发表于 2013-4-21 22:50
你的锁有问题。
建议把锁定义在外面。
Object obj = new Object();

哦 现在好了
回复 使用道具 举报
楼主你好:
你的同步代码块里面的锁有问题,因为你用的是匿名对象,每次判断锁的时候,都是不同的对象。
因为同步代码块中的锁必须是同一个锁并且可以是任意锁,可以是this锁,也可以是.class文件。
所谓的锁也就是synchronized (锁){};中传的参数你可以把对象改为如下所示:
  1. class Ticket implements Runnable {
  2. private int tic = 100;
  3. private Object obj = new Object();                  //这里定义的代码,就是定义的锁对象

  4. public void run() {
  5. while (true) {
  6. synchronized (obj) {                       //这里就是装的锁对象,其实也可以不用定义锁对象,直接传个任意对象就行,如this或者某类的.class文件都可以,保证锁的唯一
  7. if (tic > 0) {
  8. try {
  9. Thread.sleep(10);// 出现-1、-2号票 有安全问题
  10. } catch (InterruptedException e) {
  11. e.printStackTrace();
  12. }
  13. System.out.println(Thread.currentThread().getName()
  14. + "ticket" + tic--);
  15. }
  16. }
  17. }
  18. }
  19. }

  20. public class TicketDemo {
  21. public static void main(String[] args) {

  22. Ticket t = new Ticket();
  23. Thread t1 = new Thread(t);
  24. Thread t2 = new Thread(t);
  25. Thread t3 = new Thread(t);
  26. Thread t4 = new Thread(t);
  27. t1.start();
  28. t2.start();
  29. t3.start();
  30. t4.start();

  31. }
  32. }
复制代码
希望可以帮助楼主。

评分

参与人数 1技术分 +2 收起 理由
张熙韬 + 2

查看全部评分

回复 使用道具 举报
不能在锁对象那new对象的,这样每次都是新的对象
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马