sky5412
2020-04-07 20:58
采纳率: 57.1%
浏览 258
已采纳

java实现同步多线程的问题

卖票的代码,无法实现完整的多线程,只有一两个线程会输出。
import java.util.Scanner;

class MyThread implements Runnable{
private int ticket; //票数
private String name; //线程名称

public MyThread() {
    super();
}


public MyThread(int ticket,String name) {
    super();
    this.ticket = ticket;
    this.name = name;
}

public int getTicket() {
    return ticket;
}


public void setTicket(int ticket) {
    this.ticket = ticket;
}


public String getName() {
    return name;
}


public void setName(String name) {
    this.name = name;
}
@Override
public void run() {  //控制线程输出
    int t = this.ticket;
    synchronized(this){   //同步线程
        for(int i = 1;i<=t;i++) {
        if(this.ticket>0) {
            System.out.println(this.name+",当前余票是:"+(this.ticket-1)+".售出票号是:"+i);
        }
        this.ticket--;

    }
    }
}

}
public class Main {

public static void main(String[] args) {
    Scanner in = new Scanner(System.in);
    System.out.println("请输入总的票数:");
    int ticketNum = in.nextInt();
    System.out.println("请输入窗口数目:");
    int num = in.nextInt();
    MyThread mt = new MyThread();
       for(int i = 1;i<=num;i++) {
           mt.setName("售票窗口"+i+"正在售票"); 
           mt.setTicket(ticketNum);
           new Thread(mt).start();
       }
}

}
以下为代码运行结果:
图片说明
麻烦大佬们解答一下,谢谢!
ps:为什么在主方法的设置多线程for循环那里,将创建和实例化对象放入for循环中,就无法实现同步线程呢?

  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

5条回答 默认 最新

  • 毕小宝 2020-04-08 07:33
    已采纳

    有两个问题:
    1、之所以只看到一个线程的输出信息,setName 使用的是同一个 MyThread ,每次都覆盖上次的值,最后只有一个 5 的时候生效了,把 new MyThread 挪到内部。
    2、同步的逻辑有问题,购票的票数应该是所有线程共享的,应该设置为静态变量,所有线程用同一个锁,保证票数一致。
    调整代码如下:

    
    import java.util.Scanner;
    
    class MyThread implements Runnable {
        private static int ticket; // 票数
        private String name; // 线程名称
    
        public MyThread() {
            super();
        }
    
        public MyThread(int ticket, String name) {
            super();
            this.name = name;
        }
    
        public int getTicket() {
            return ticket;
        }
    
        public static void setTicket(int ticket) {
            MyThread.ticket = ticket;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public void run() { // 控制线程输出
            while(ticket>0) {
                synchronized (MyThread.class) { // 同步线程
                    System.out.println(this.name + ",当前余票是:" + (ticket - 1) + ".售出票号是:" + ticket);
                    ticket--;
                }
    
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public static void main(String[] args) {
            Scanner in = new Scanner(System.in);
            System.out.println("请输入总的票数:");
            int ticketNum = in.nextInt();
            System.out.println("请输入窗口数目:");
            int num = in.nextInt();
            MyThread.setTicket(ticketNum);
            for (int i = 1; i <= num; i++) {
                MyThread mt = new MyThread();
                mt.setName("售票窗口" + i + "正在售票");
                new Thread(mt).start();
            }
            in.close();
        }
    }
    
    

    这样就就正常了,有需要可以关注我的Java并发编程专栏,里面有解释这类常见问题。

    已采纳该答案
    评论
    解决 无用
    打赏 举报
  • franzhong 2020-04-07 21:50

    实现同步线程,用synchronized嵌套下for试试

    synchronized (this) {
    。。。
    }
    
    评论
    解决 无用
    打赏 举报
  • synchronized 这个关键字表示同步,你使用 synchronized表示当前只允许一个线程操作,其他线程等待操作,当第一个线程结束后,开始第二个
    悲观锁。具有排它锁。

    评论
    解决 无用
    打赏 举报
  • 1024工程师 2020-04-07 22:28

    你好,创建实例化对象放在for循环中不能实现同步线程。若创建的对象放在里面,则意思完全不一样,是对不同的对象进行线程操作,而多线程是要对同一个对象进行操作

    评论
    解决 无用
    打赏 举报
  • 普通码农 2020-04-07 22:33

    增加票数,每买一张票睡眠1s,这样能让线程卖票数变得更加分散

    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题