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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 未成曲调 中级黑马   /  2016-4-19 19:12  /  506 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

/*
题目:
        定义一个类实现Runnable接口,卖票100张,四个线程,输出格式为“窗口1,还剩10张票”
        ,指定窗口3卖第10张票。
思路:
        1、定义一个资源类实现Runnable接口
        2、资源类重写run()方法,并加锁卖票
        3、在测试类中创建线程并启动
*/
class SellTicket
{
        public static void main(String[] args)
        {
                //创建一个资源对象
                Tickets ticket = new Tickets();
                //创建线程对象并传入资源对象
                Thread t1 = new Thread(ticket);
                Thread t2 = new Thread(ticket);
                Thread t3 = new Thread(ticket);
                Thread t4 = new Thread(ticket);
                //设置线程名称
                t1.setName("窗口1");
                t2.setName("窗口2");
                t3.setName("窗口3");
                t4.setName("窗口4");
                //启动线程
                t1.start();
                t2.start();
                t3.start();
                t4.start();
        }
}

class Tickets implements Runnable
{
        private int ticket = 100;
        @Override
        public void run()
        {
                while(true)
                {
                        //加锁
                        synchronized(this)
                        {
                                //剩余票数不大于0就退出循环
                                if(ticket > 0)
                                {
                                        try
                                        {
                                                Thread.sleep(100);
                                        } catch (InterruptedException e)
                                        {
                                                e.printStackTrace();
                                        }
                                        //让窗口3卖第十张票
                                        if(ticket == 10)
                                        {
                                                if(!Thread.currentThread().getName().equals("窗口3"))
                                                {
                                                        continue;
                                                }
                                        }
                                        System.out.println(Thread.currentThread().getName()+",还剩"+ ( --ticket )+"张票");
                                }
                                else
                                {
                                        break;
                                }
                        }
                }
        }
}

4 个回复

倒序浏览
打酱油................
回复 使用道具 举报
牛逼啊
回复 使用道具 举报
楼主,你这个好像是让窗口三卖出第90张的意思ticket 是从100开始递减的,应该判断ticket == 90吧
回复 使用道具 举报
看楼主写的好像还有其他错误 所以自己也写了一下  如有不足请指出哈!
楼主的票数变量声明有问题, 应该使用静态static
同步锁对象使用错误,使用this每次锁对象都会变,this不唯一,class是唯一的
不应该使用sleep  sleep是进入睡眠 不释放锁对象,应使用wait  wait是进入等待状态,需要主动唤醒  进入等待时 释放锁对象

  1. public class Test {

  2.         public static void main(String[] args) {
  3.                 Thread t1 = new Thread(new Tickets());
  4.                 Thread t2 = new Thread(new Tickets());
  5.                 Thread t3 = new Thread(new Tickets());
  6.                 Thread t4 = new Thread(new Tickets());
  7.                 t1.setName("窗口1");
  8.                 t2.setName("窗口2");
  9.                 t3.setName("窗口3");
  10.                 t4.setName("窗口4");
  11.                 t1.start();
  12.                 t2.start();
  13.                 t3.start();
  14.                 t4.start();
  15.         }

  16. }
  17. class Tickets implements Runnable {
  18.         //将票数定义为静态变量  所有此对象共享,不会出现每new一次都是100
  19.         private static int ticket = 100;
  20.         @Override
  21.         public void run() {
  22.                 while (true) {
  23.                         //同步 因为是多线程锁对象 不能使用this 使用this为谁调用我 我就是谁,显然多个线程每次锁对象都不同起不到效果
  24.                         //在这里需要使用字节码文件当做 锁对象,因为字节码文件是不会因对象改变而被改变的 无论多少线程 字节码文件都唯一
  25.                         synchronized (Tickets.class) {
  26.                                 //票数小于0跳出循环
  27.                                 if (ticket > 0) {
  28.                                         //票数为90  因为ticket从100开始自减 90正好是第10张
  29.                                         //票数为90  窗口不为3 线程进入等待 交出控制权 释放锁对象
  30.                                         if (ticket == 90 && !"窗口3".equals(Thread.currentThread().getName())) {
  31.                                                 try {
  32.                                                         System.out.println(Thread.currentThread().getName()+"等待");
  33.                                                         //线程进入等待
  34.                                                         Tickets.class.wait();
  35.                                                         //恢复线程恢复后进入到循环尾部从新开始,防止继续进行操作
  36.                                                         continue;
  37.                                                 } catch (InterruptedException e) {
  38.                                                         e.printStackTrace();
  39.                                                 }
  40.                                         }
复制代码





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