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循环中,就无法实现同步线程呢?

有两个问题:
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并发编程专栏,里面有解释这类常见问题。

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

synchronized (this) {
。。。
}

synchronized 这个关键字表示同步,你使用 synchronized表示当前只允许一个线程操作,其他线程等待操作,当第一个线程结束后,开始第二个
悲观锁。具有排它锁。

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

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