黑马程序员技术交流社区

标题: 多线程问题 [打印本页]

作者: 许聪聪    时间: 2013-6-3 00:04
标题: 多线程问题
本帖最后由 许聪聪 于 2013-6-12 16:57 编辑
  1. /*
  2. * 练习:卖票系统。运用多线程。
  3. * 先对票进行描述
  4. * 分四个窗口同时卖票,需要开启4个线程。
  5. */
  6. //实现接口Runnable
  7. class Ticket implements Runnable{
  8.         private int tickets = 100;
  9.         Object obj = new Object();
  10.         //覆盖run方法
  11.         public void run(){
  12.                
  13.                 while (tickets>0){
  14.                         synchronized (obj){
  15.                
  16.                                 System.out.println(Thread.currentThread().getName()+"···"+tickets--);
  17.                                 
  18.                                 }
  19.                     }
  20.                 }
  21.         }
  22. class TicketTest{
  23.         public static void main(String[] args){
  24.                 Ticket d = new Ticket();
  25.                 Thread t1 = new Thread(d);
  26.                 Thread t2 = new Thread(d);
  27.                 Thread t3 = new Thread(d);
  28.                 Thread t4 = new Thread(d);
  29.                 t1.start();
  30.                 t2.start();
  31.                 t3.start();
  32.                 t4.start();
  33.         }
  34. }
复制代码
不好意思 第一发帖   我发的问题发在code里了    问题是:这个程序出来会出现负票。让别人解决。他们说while 要进行无限循环。不用无线循环行吗?怎么才不会出现负数票。加同步锁也不好使。
作者: 金辉    时间: 2013-6-3 00:58
while (tickets>0){
                        synchronized (obj){
                                   if (tickets>0)
                                System.out.println(Thread.currentThread().getName()+"···"+tickets--);
                                
                                }
                    }
在里边再判断下,因为当你循环的时候比如说线程0已经在卖出最后一张票,在进入同步代码块之前,有可能其它线程在这时夺走cpu执行权,进入while循环,这时0线程又取回执行权,当它执行完,此时票已卖完。但在while中还有阻塞的线程,它们此时执行就会出现票为负数的情况。
作者: 神之梦    时间: 2013-6-3 01:07
楼主的问题在哪???????????
作者: 狂飙的yellow.co    时间: 2013-6-3 21:45
我发现错误在哪儿了,错误是......................不打印数据
作者: 狂飙的yellow.co    时间: 2013-6-3 22:03
本帖最后由 狂飙的yellow.co 于 2013-6-4 08:00 编辑

我发现了错误
嘎嘎
  1. package ThreadDemo;

  2. /*
  3. * 练习:卖票系统。运用多线程。
  4. * 先对票进行描述
  5. * 分四个窗口同时卖票,需要开启4个线程。
  6. */
  7. //实现接口Runnable
  8. class Ticket implements Runnable {
  9.         
  10.         private int tickets = 100;
  11.         Object obj = new Object();//对象锁
  12.         // 覆盖run方法
  13.         
  14.         public void run() {
  15.                 while(true){
  16.                         synchronized (obj) {
  17.                                 while(tickets >0){
  18.                                         System.out.println(Thread.currentThread().getName()+"_______"+tickets--);
  19.                                 }
  20.                         }
  21.                 }
  22.         }
  23. }

  24. public class TicketTest {
  25.         public static void main(String[] args) {
  26.                 Ticket d = new Ticket();
  27.                 new Thread(d).start();
  28.         }
  29. }
复制代码
其中错误在run方法中,要使用的是无限循环加上判断
  1. public void run() {
  2.                 while(true){
  3.                         synchronized (obj) {
  4.                                while(tickets >0){
  5.                                         System.out.println(Thread.currentThread().getName()+"_______"+tickets--);
  6.                                 }
  7.                         }
  8.                 }
  9.         }
复制代码

作者: 傻瓜一点红    时间: 2013-6-3 22:07
{:soso_e127:}楼主你这毛问题都木有,发这贴浪费感情了,你要发感言也行啊........
作者: 黑马-雷钊    时间: 2013-6-3 23:42
public void run(){
               synchronized (obj){
                while (tickets>0){
                                System.out.println(Thread.currentThread().getName()+"···"+tickets--);
                                
                                }
                    }
                }
亲,你把锁放在循环外面啊。这样每次就只有一个线程能进来判断票数是不是0了。你把锁放外面很可能一个线程进了循环就挂掉了。然后又一个线程进来判断锁里面有没有线程?不管有没有,最后两个线程都会执行循环体的对不对?因为锁不能判断票数,只要所里面没有线程其它线程进来就可以执行。把锁放在外面整个循环就只能进一个线程了。这样每次循环里面就只存在一个线程。就不存在负数票了
作者: yin1031468524    时间: 2013-6-4 00:17
  1. package com.itheima;
  2. /*
  3. * 练习:卖票系统。运用多线程。
  4. * 先对票进行描述
  5. * 分四个窗口同时卖票,需要开启4个线程。
  6. */
  7. //实现接口Runnable
  8. class Ticket implements Runnable{
  9.         private int tickets = 100;
  10.         Object obj = new Object();
  11.         //覆盖run方法
  12.         public void run(){
  13.                
  14.                 while (tickets>0){
  15.                         //在剩下最后1张票时候有可能四个线程都运行到此处
  16.                         synchronized (obj){
  17.                                 //如果此处不判断tickets是否>0,则此处tickets可能为负数,还可以把锁放到while循环外面
  18.                                 if(tickets>0)
  19.                                 System.out.println(Thread.currentThread().getName()+"···"+tickets--);
  20.                                 
  21.                                 }
  22.                     }
  23.                 }
  24.         }
  25. class TicketTest{
  26.         public static void main(String[] args){
  27.                 Ticket d = new Ticket();
  28.                 Thread t1 = new Thread(d);
  29.                 Thread t2 = new Thread(d);
  30.                 Thread t3 = new Thread(d);
  31.                 Thread t4 = new Thread(d);
  32.                 t1.start();
  33.                 t2.start();
  34.                 t3.start();
  35.                 t4.start();
  36.         }
  37. }
复制代码
解释见注释部分、、
作者: 花心々小土豆    时间: 2013-6-4 09:45
毕老师基础视频多线程中经典例子,强烈建议楼主再看一遍!
作者: 宋旭东    时间: 2013-7-2 21:36
这个问题很简单,给你个不用while循环的。
public void run()
        {
                synchronized(Demo.class)
                {
                        for(;num>0;num--)
                        {
                                System.out.println("卖出"+num+"号票");
                        }
                }
        }




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2