黑马程序员技术交流社区
标题:
多线程之卖票难题
[打印本页]
作者:
未成曲调
时间:
2016-4-19 19:12
标题:
多线程之卖票难题
/*
题目:
定义一个类实现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;
}
}
}
}
}
作者:
Muhaicheng
时间:
2016-4-19 19:17
打酱油................
作者:
JeffTang
时间:
2016-4-19 19:47
牛逼啊
作者:
神祈灬丨狂想曲
时间:
2016-4-19 23:47
楼主,你这个好像是让窗口三卖出第90张的意思ticket 是从100开始递减的,应该判断ticket == 90吧
作者:
神祈灬丨狂想曲
时间:
2016-4-20 00:26
看楼主写的好像还有其他错误 所以自己也写了一下 如有不足请指出哈!
楼主的票数变量声明有问题, 应该使用静态static
同步锁对象使用错误,使用this每次锁对象都会变,this不唯一,class是唯一的
不应该使用sleep sleep是进入睡眠 不释放锁对象,应使用wait wait是进入等待状态,需要主动唤醒 进入等待时 释放锁对象
public class Test {
public static void main(String[] args) {
Thread t1 = new Thread(new Tickets());
Thread t2 = new Thread(new Tickets());
Thread t3 = new Thread(new Tickets());
Thread t4 = new Thread(new Tickets());
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t4.setName("窗口4");
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Tickets implements Runnable {
//将票数定义为静态变量 所有此对象共享,不会出现每new一次都是100
private static int ticket = 100;
@Override
public void run() {
while (true) {
//同步 因为是多线程锁对象 不能使用this 使用this为谁调用我 我就是谁,显然多个线程每次锁对象都不同起不到效果
//在这里需要使用字节码文件当做 锁对象,因为字节码文件是不会因对象改变而被改变的 无论多少线程 字节码文件都唯一
synchronized (Tickets.class) {
//票数小于0跳出循环
if (ticket > 0) {
//票数为90 因为ticket从100开始自减 90正好是第10张
//票数为90 窗口不为3 线程进入等待 交出控制权 释放锁对象
if (ticket == 90 && !"窗口3".equals(Thread.currentThread().getName())) {
try {
System.out.println(Thread.currentThread().getName()+"等待");
//线程进入等待
Tickets.class.wait();
//恢复线程恢复后进入到循环尾部从新开始,防止继续进行操作
continue;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
复制代码
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2