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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 魏冬 中级黑马   /  2012-12-11 23:16  /  1395 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

class tickte implements Runnable{
        private int tickets=100;
        public void run(){
                for(int i=1;i<tickets;tickets--){
                        System.out.println(Thread.currentThread().getName()+"-----"+tickets);
                }
        }
}
public class 线程_2 {
        public static void main(String[] args){
                tickte t=new tickte();
                Thread t1=new Thread(t);
                Thread t2=new Thread(t);
                Thread t3=new Thread(t);
                Thread t4=new Thread(t);
                t1.start();
                t2.start();
                t3.start();
                t4.start();
创建线程声明实现了Runnable接口的类。覆盖了接口中的run方法。为什么用Runnable接口做会打印多个100呢?  求高手指点???

QQ截图20121211231516.png (3.52 KB, 下载次数: 9)

QQ截图20121211231516.png

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1 赞一个!

查看全部评分

4 个回复

倒序浏览
class tickte implements Runnable{
         private int tickets=100;
                 Object obj = new Object();
         public void run(){
                         
                                        for(int i=1;i<tickets;tickets--){
                                                 if(tickets>0)
                                                    System.out.println(Thread.currentThread().getName()+"-----"+tickets--);
                                        }
                               
                       
         }
}
class ThreadTest5
{
        public static void main(String[] args)
        {
                tickte t=new tickte();
        Thread t1=new Thread(t);
        Thread t2=new Thread(t);
        Thread t3=new Thread(t);
        Thread t4=new Thread(t);
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        }
}
我给你测试了一下 只出一次100啊  不过我觉得应该有安全问题吧

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1 赞一个!

查看全部评分

回复 使用道具 举报
本帖最后由 罗会涛 于 2012-12-12 12:54 编辑

多个线程并发访问和修改private int tickets=100属性,会产生安全问题。
一个线程拿到该属性,判断条件后还没有输出,或者输出后还没有来得及修改属性值,这个时候其它线程进来,拿到的属性值当然就是没经过修改的,这个新线程输出的属性值必然会和前一个相同。这个时候要对这个属性值的访问加同步,这里只需要把Ticket对象锁死就可以了,这样一个线程拿到Ticket对象的tickets属性值其它线程是无法访问到同步块中的内容。
  1.                         synchronized (this)
  2.                         {
  3.                                 System.out.println(Thread.currentThread().getName() + "-----"
  4.                                                 + tickets);
  5.                      tickets--;
  6.                         }
复制代码
这样就安全了,并且打印语句也同步了,不会出现小票号先卖出的情况。
但是到线程的最后,多个线程判断符合条件只有一个线程拿到锁进入同步块把tickets改为1,它出来后,其它线程拿到锁打印出了比2号票更小的票号。又得在打印前加判断if(tickets>1)。(还是while true配合if比较爽)

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1 赞一个!

查看全部评分

回复 使用道具 举报
罗会涛 发表于 2012-12-12 12:44
多个线程并发访问和修改private int tickets=100属性,会产生安全问题。
一个线程拿到该属性,判断条件后还 ...

while ture  不就会无限循环了么?
回复 使用道具 举报
魏冬 发表于 2012-12-12 17:17
while ture  不就会无限循环了么?

break跳出啊
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马