synchronized(this)
这个没有保证同步,这里的this代表SellTicketSystem的实例,s1.start()时用的锁是s1,s2.start()时用的锁是s2,你的代码就没有达到你想要的异步效果。在s1执行ticket--前,s2也执行到Thread.sleep(1000),卖到最后一张时,s2还会再卖一张。
把synchronized(this)改成synchronized(SellTicketSystem.class)试试。另外多线程代码结构,一般不是你这样的,先看几个例子再写吧。

解决方案 »

  1.   

    这个正常啊,最后的时候222222222买了最后一张,然后tickit--,tickit变成0了,但在22222222进入tickit>0内之后的某个时间,111也进入了这个tickit>0,这时的tickit还是1,只是222222222要比111快,所以22222222先执行了 System.out.println(this.getName()+"卖到第"+ticket--+"张");这时的tickit=0;接着111也执行了 System.out.println(this.getName()+"卖到第"+ticket--+"张");但是这时的tickit变成了0
      

  2.   

    synchronized(this)
    这个没有保证同步,这里的this代表SellTicketSystem的实例,s1.start()时用的锁是s1,s2.start()时用的锁是s2,你的代码就没有达到你想要的异步效果。在s1执行ticket--前,s2也执行到Thread.sleep(1000),卖到最后一张时,s2还会再卖一张。
    把synchronized(this)改成synchronized(SellTicketSystem.class)试试。另外多线程代码结构,一般不是你这样的,先看几个例子再写吧。就像楼上说的,你这不是锁,要锁住就用synchronized,另外jdk的java.util.current包下还有一些信号灯之类的东西,也很不错,多看看学学吧!
      

  3.   

    public class Demo2 { public static void main(String[] args) {
    SellTicketSystem s1 = new SellTicketSystem();
    SellTicketSystem s2 = new SellTicketSystem();
    s1.setName("111");
    s2.setName("2222222222"); s1.start();
    s2.start();
    }
    }class SellTicketSystem extends Thread {
    private static int ticket = 20;
    private static byte[] b = new byte[] { 1 }; public void run() {
    while (true) {
    if (ticket > 0) {
    try {
    Thread.sleep(1000);
    } catch (Exception e) {
    e.printStackTrace();
    }
    synchronized (b) {
    System.out.println(this.getName() + "卖到第" + ticket-- + "张");
    }
    }
    }
    }}
      

  4.   

    synchronized(this)
    这个没有保证同步,这里的this代表SellTicketSystem的实例,s1.start()时用的锁是s1,s2.start()时用的锁是s2,你的代码就没有达到你想要的异步效果。在s1执行ticket--前,s2也执行到Thread.sleep(1000),卖到最后一张时,s2还会再卖一张。
    把synchronized(this)改成synchronized(SellTicketSystem.class)试试。另外多线程代码结构,一般不是你这样的,先看几个例子再写吧。你这方法结果是:
    111卖到第20张
    111卖到第19张
    111卖到第18张
    111卖到第17张
    111卖到第16张
    111卖到第15张
    111卖到第14张
    111卖到第13张
    111卖到第12张
    111卖到第11张
    111卖到第10张
    111卖到第9张
    111卖到第8张
    111卖到第7张
    111卖到第6张
    111卖到第5张
    111卖到第4张
    111卖到第3张
    111卖到第2张
    111卖到第1张
    这样的话222222222就卖不了票了
      

  5.   

    synchronized(this)
    这个没有保证同步,这里的this代表SellTicketSystem的实例,s1.start()时用的锁是s1,s2.start()时用的锁是s2,你的代码就没有达到你想要的异步效果。在s1执行ticket--前,s2也执行到Thread.sleep(1000),卖到最后一张时,s2还会再卖一张。
    把synchronized(this)改成synchronized(SellTicketSystem.class)试试。另外多线程代码结构,一般不是你这样的,先看几个例子再写吧。你这方法结果是:
    111卖到第20张
    111卖到第19张
    111卖到第18张
    111卖到第17张
    111卖到第16张
    111卖到第15张
    111卖到第14张
    111卖到第13张
    111卖到第12张
    111卖到第11张
    111卖到第10张
    111卖到第9张
    111卖到第8张
    111卖到第7张
    111卖到第6张
    111卖到第5张
    111卖到第4张
    111卖到第3张
    111卖到第2张
    111卖到第1张
    这样的话222222222就卖不了票了
    你这个其实已经卖关了,只是减到了0(1是ticket--写法造成的)
      

  6.   

    System.out.println(this.getName()+"剩余:"+ticket--+"张");
      

  7.   

    synchronized(this)
    这个没有保证同步,这里的this代表SellTicketSystem的实例,s1.start()时用的锁是s1,s2.start()时用的锁是s2,你的代码就没有达到你想要的异步效果。在s1执行ticket--前,s2也执行到Thread.sleep(1000),卖到最后一张时,s2还会再卖一张。
    把synchronized(this)改成synchronized(SellTicketSystem.class)试试。另外多线程代码结构,一般不是你这样的,先看几个例子再写吧。你这方法结果是:
    111卖到第20张
    111卖到第19张
    111卖到第18张
    111卖到第17张
    111卖到第16张
    111卖到第15张
    111卖到第14张
    111卖到第13张
    111卖到第12张
    111卖到第11张
    111卖到第10张
    111卖到第9张
    111卖到第8张
    111卖到第7张
    111卖到第6张
    111卖到第5张
    111卖到第4张
    111卖到第3张
    111卖到第2张
    111卖到第1张
    这样的话222222222就卖不了票了
    你这个其实已经卖关了,只是减到了0(1是ticket--写法造成的)哥们儿,不知道你运行了没有这tickit--是先执行,再减1,最后tickit的值是-1,不是0,懂否???
      

  8.   

    我告诉你把synchronized(this)改成synchronized(SellTicketSystem.class),是为了告诉你锁怎么用,不是说改这个你的代码就能完成你的想法(2个窗户同时售票),我后面说了,多线程代码结构就不是你这样的。
    222222222不卖票的原因是锁的位置不对,一个线程一直占用,一直到票卖光了,另一个线程才能执行锁内的代码。public class Demo2{
        public static void main(String [] args){
            Stack stack = new Stack();
            SellTicketSystem s1 = new SellTicketSystem(stack,"111");
            SellTicketSystem s2 = new SellTicketSystem(stack,"2222222222");
            s1.start();
            s2.start();
        }
    }
    //共享数据
    class Stack{
        public int ticket=20;
        public synchronized void sell(String name) {
            int t = ticket--;
            System.out.println(name+"卖到第"+t+"张");
            try{
                Thread.sleep(1000);
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
    class SellTicketSystem extends Thread{
        private Stack stack;
        private String name;
        public SellTicketSystem(Stack stack,String name){
            super();
            this.stack = stack;
            this.name = name;
        }
        public void run(){
            while (stack.ticket>0) {
                this.stack.sell(this.name);
            }
        }
    }
      

  9.   

    synchronized(this)
    这个没有保证同步,这里的this代表SellTicketSystem的实例,s1.start()时用的锁是s1,s2.start()时用的锁是s2,你的代码就没有达到你想要的异步效果。在s1执行ticket--前,s2也执行到Thread.sleep(1000),卖到最后一张时,s2还会再卖一张。
    把synchronized(this)改成synchronized(SellTicketSystem.class)试试。另外多线程代码结构,一般不是你这样的,先看几个例子再写吧。你这方法结果是:
    111卖到第20张
    111卖到第19张
    111卖到第18张
    111卖到第17张
    111卖到第16张
    111卖到第15张
    111卖到第14张
    111卖到第13张
    111卖到第12张
    111卖到第11张
    111卖到第10张
    111卖到第9张
    111卖到第8张
    111卖到第7张
    111卖到第6张
    111卖到第5张
    111卖到第4张
    111卖到第3张
    111卖到第2张
    111卖到第1张
    这样的话222222222就卖不了票了
    你这个其实已经卖关了,只是减到了0(1是ticket--写法造成的)哥们儿,不知道你运行了没有这tickit--是先执行,再减1,最后tickit的值是-1,不是0,懂否???ticket==1
    输出ticket--时,打印的是1好不,但这时ticket的值变成了0;!!
      

  10.   

    synchronized(this)
    这个没有保证同步,这里的this代表SellTicketSystem的实例,s1.start()时用的锁是s1,s2.start()时用的锁是s2,你的代码就没有达到你想要的异步效果。在s1执行ticket--前,s2也执行到Thread.sleep(1000),卖到最后一张时,s2还会再卖一张。
    把synchronized(this)改成synchronized(SellTicketSystem.class)试试。另外多线程代码结构,一般不是你这样的,先看几个例子再写吧。你这方法结果是:
    111卖到第20张
    111卖到第19张
    111卖到第18张
    111卖到第17张
    111卖到第16张
    111卖到第15张
    111卖到第14张
    111卖到第13张
    111卖到第12张
    111卖到第11张
    111卖到第10张
    111卖到第9张
    111卖到第8张
    111卖到第7张
    111卖到第6张
    111卖到第5张
    111卖到第4张
    111卖到第3张
    111卖到第2张
    111卖到第1张
    这样的话222222222就卖不了票了111运行时加上锁,用运行一圈后,你没有解锁,所以2222222跟本得不到资源,怎么运行???这个程序实现就是让他你一下,我一下,你一下,我一下,这样就要来回的加锁解锁,加锁解锁,你这有加锁,跟本没解锁啊,用一下信号灯吧,去网看一下有关知识,实现更简单
      

  11.   

    synchronized(this)
    这个没有保证同步,这里的this代表SellTicketSystem的实例,s1.start()时用的锁是s1,s2.start()时用的锁是s2,你的代码就没有达到你想要的异步效果。在s1执行ticket--前,s2也执行到Thread.sleep(1000),卖到最后一张时,s2还会再卖一张。
    把synchronized(this)改成synchronized(SellTicketSystem.class)试试。另外多线程代码结构,一般不是你这样的,先看几个例子再写吧。你这方法结果是:
    111卖到第20张
    111卖到第19张
    111卖到第18张
    111卖到第17张
    111卖到第16张
    111卖到第15张
    111卖到第14张
    111卖到第13张
    111卖到第12张
    111卖到第11张
    111卖到第10张
    111卖到第9张
    111卖到第8张
    111卖到第7张
    111卖到第6张
    111卖到第5张
    111卖到第4张
    111卖到第3张
    111卖到第2张
    111卖到第1张
    这样的话222222222就卖不了票了
    你这个其实已经卖关了,只是减到了0(1是ticket--写法造成的)哥们儿,不知道你运行了没有这tickit--是先执行,再减1,最后tickit的值是-1,不是0,懂否???ticket==1
    输出ticket--时,打印的是1好不,但这时ticket的值变成了0;!!对啊,这没错啊,然后下一轮得到的就是0了啊,这跟本不是ticket--的问题啊,买了票后,当然少一张票,所以这个写法没问题,有问题的还是线程同步上,楼主得到的2一下,1一下,来回交换只是一个巧合,巧合而已
      

  12.   

    抛开线程不说
    if(ticket>0)这个判断条件加上 ticket-- 这个输出肯定是会出现0的啊,如果ticket==1>0,自然满足条件然后输出 ticket-- = 0 不是很正常吗
      

  13.   

    正常什么?
    你执行下一段代码先试一试再说.
    int ticket = 1;
    if(ticket>0){
    //这时1>0,所以能进来
    System.out.println(ticket--);//这里打印的是1,而不是0,你要先搞明白ticket-- 。
    }
      

  14.   

    synchronized(this)
    这个没有保证同步,这里的this代表SellTicketSystem的实例,s1.start()时用的锁是s1,s2.start()时用的锁是s2,你的代码就没有达到你想要的异步效果。在s1执行ticket--前,s2也执行到Thread.sleep(1000),卖到最后一张时,s2还会再卖一张。
    把synchronized(this)改成synchronized(SellTicketSystem.class)试试。另外多线程代码结构,一般不是你这样的,先看几个例子再写吧。你这方法结果是:
    111卖到第20张
    111卖到第19张
    111卖到第18张
    111卖到第17张
    111卖到第16张
    111卖到第15张
    111卖到第14张
    111卖到第13张
    111卖到第12张
    111卖到第11张
    111卖到第10张
    111卖到第9张
    111卖到第8张
    111卖到第7张
    111卖到第6张
    111卖到第5张
    111卖到第4张
    111卖到第3张
    111卖到第2张
    111卖到第1张
    这样的话222222222就卖不了票了111运行时加上锁,用运行一圈后,你没有解锁,所以2222222跟本得不到资源,怎么运行???这个程序实现就是让他你一下,我一下,你一下,我一下,这样就要来回的加锁解锁,加锁解锁,你这有加锁,跟本没解锁啊,用一下信号灯吧,去网看一下有关知识,实现更简单
    那有什么实现的方法么?
      

  15.   

    正常什么?
    你执行下一段代码先试一试再说.
    int ticket = 1;
    if(ticket>0){
    //这时1>0,所以能进来
    System.out.println(ticket--);//这里打印的是1,而不是0,你要先搞明白ticket-- 。
    }额是的,我粗心了,ticket--实际上是先输出ticket然后再执行ticket--的,说明线程A和线程B在ticket==1的时候同时进来,然后A把ticket--了,而B仍然输出ticket,此时就输出了被A减过的ticket就是0
      

  16.   

    我告诉你把synchronized(this)改成synchronized(SellTicketSystem.class),是为了告诉你锁怎么用,不是说改这个你的代码就能完成你的想法(2个窗户同时售票),我后面说了,多线程代码结构就不是你这样的。
    222222222不卖票的原因是锁的位置不对,一个线程一直占用,一直到票卖光了,另一个线程才能执行锁内的代码。public class Demo2{
        public static void main(String [] args){
            Stack stack = new Stack();
            SellTicketSystem s1 = new SellTicketSystem(stack,"111");
            SellTicketSystem s2 = new SellTicketSystem(stack,"2222222222");
            s1.start();
            s2.start();
        }
    }
    //共享数据
    class Stack{
        public int ticket=20;
        public synchronized void sell(String name) {
            int t = ticket--;
            System.out.println(name+"卖到第"+t+"张");
            try{
                Thread.sleep(1000);
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
    class SellTicketSystem extends Thread{
        private Stack stack;
        private String name;
        public SellTicketSystem(Stack stack,String name){
            super();
            this.stack = stack;
            this.name = name;
        }
        public void run(){
            while (stack.ticket>0) {
                this.stack.sell(this.name);
            }
        }
    }

    为什么是全部是从20张票减少,而不是各自减去各自的
      

  17.   

    正常什么?
    你执行下一段代码先试一试再说.
    int ticket = 1;
    if(ticket>0){
    //这时1>0,所以能进来
    System.out.println(ticket--);//这里打印的是1,而不是0,你要先搞明白ticket-- 。
    }关键是要执行原子操作,而while(true)这段代码无法保证整个都是原子性的,因为ticket==1的时候A和B线程可以同时有效,然后我自定义了一组信号量,可以保证A和B交替执行并且最后ticket不为0
    public static class Demo2{ public static void main(String [] args){
    SellTicketSystem s1 = new SellTicketSystem();
    SellTicketSystem s2 = new SellTicketSystem();
    s1.setName("111");
    s2.setName("2222222222");
    //System.out.println("sdsd");
    s1.start();
    s2.start();

    }
    }
    static class SellTicketSystem extends Thread{
    private static int mutex = 1;
    private static String name = "2222222222";//另一个线程先开始
    private boolean _wait(){
    //确保上一次另一个线程拿到了资源
    if(mutex==1 && !name.equals(this.getName())){
    name = this.getName();
    mutex--;
    return true;
    }else{
    return false;
    }
    }
    private void _signal(){
    if(mutex==0 && ticket>0){
    mutex++;
    }
    }
    private static int ticket=20;
    public void run(){
    while(ticket>0){
    if(ticket>0){
    try{
    Thread.sleep(10);
    }catch(Exception e){
    e.printStackTrace();
    }
    if(_wait()){
    System.out.println(this.getName()+"卖到第"+ticket--+"张");
    _signal();
    }
    }
    }
    }}
      

  18.   

    正常什么?
    你执行下一段代码先试一试再说.
    int ticket = 1;
    if(ticket>0){
    //这时1>0,所以能进来
    System.out.println(ticket--);//这里打印的是1,而不是0,你要先搞明白ticket-- 。
    }关键是要执行原子操作,而while(true)这段代码无法保证整个都是原子性的,因为ticket==1的时候A和B线程可以同时有效,然后我自定义了一组信号量,可以保证A和B交替执行并且最后ticket不为0
    public static class Demo2{ public static void main(String [] args){
    SellTicketSystem s1 = new SellTicketSystem();
    SellTicketSystem s2 = new SellTicketSystem();
    s1.setName("111");
    s2.setName("2222222222");
    //System.out.println("sdsd");
    s1.start();
    s2.start();

    }
    }
    static class SellTicketSystem extends Thread{
    private static int mutex = 1;
    private static String name = "2222222222";//另一个线程先开始
    private boolean _wait(){
    //确保上一次另一个线程拿到了资源
    if(mutex==1 && !name.equals(this.getName())){
    name = this.getName();
    mutex--;
    return true;
    }else{
    return false;
    }
    }
    private void _signal(){
    if(mutex==0 && ticket>0){
    mutex++;
    }
    }
    private static int ticket=20;
    public void run(){
    while(ticket>0){
    if(ticket>0){
    try{
    Thread.sleep(10);
    }catch(Exception e){
    e.printStackTrace();
    }
    if(_wait()){
    System.out.println(this.getName()+"卖到第"+ticket--+"张");
    _signal();
    }
    }
    }
    }}
    额,好像会产生死锁,等会我再研究下
      

  19.   

    synchronized加上和不加上没有区别
      

  20.   

    我看楼主的代码理解,他是想要2个窗口一起卖20张票,就给他写了这样的代码。多线程 生产者消费者
    http://blog.csdn.net/shijinupc/article/details/7250407这个多线程的例子非常经典,把这个例子搞懂,再能根据不同情况重写一个例子,多线程的基本使用就没问题了。
      

  21.   

    http://www.cnblogs.com/rollenholt/archive/2011/08/28/2156357.html
    这篇文章能够解决你的问题
      

  22.   

    为什么不把ticket锁起来 private static Integer ticket=30; synchronized(ticket);