擦,你的tickNum是会变动的,每个线程都是一个新的tickNum,这怎么锁的住

解决方案 »

  1.   


    import java.util.concurrent.atomic.AtomicInteger;public class SellTickets
    {
        public static void main(String[] args)
        {
            SellWindow sellWindow = new SellWindow();
            for (int i = 1; i < 4; i++)
            {
                new Thread(sellWindow, String.valueOf(i)).start();
            }
        }
    }
    class SellWindow implements Runnable
    {
        private AtomicInteger tickNum = new AtomicInteger(0);
        
        boolean flag = true;
        @Override
        public void run()
        {
            synchronized(tickNum)
            {
                while(tickNum.getAndIncrement() < 50)
                {      
                      System.out.println("窗口 " + Thread.currentThread().getName() + " 已售出第 " +tickNum.get() + " 张票");            
                }
                
            }
          
        }
    }
      

  2.   


    求解,我加了static还是不行~而且我是实现Runnable接口,新的线程使用的是同一个对象里的资源,所以每个线程访问的都是同一个内存区域的tickNum,卖票的数目上是对了,但是顺序会出现问题,请问该如何解,
      

  3.   


    非常感谢,请问我是因为什么原因而得不到正确的结果呢,现在初学线程很迷茫,望赐教~
    AtomicInteger是原子变量,用它差不多可以不加锁了
      

  4.   

    package thread;/**
     * Created by zx on 2014/8/11.
     */
    public class SellTickets {
    public static void main(String[] args) {
    SellWindow sellWindow = new SellWindow();
    for (int i = 1; i < 4; i++) {
    new Thread(sellWindow, String.valueOf(i)).start();
    }
    }
    }class SellWindow implements Runnable {
    Integer tickNum = 50;
    boolean flag = true; public void run() {
    while (true) {
    synchronized (this) {
    if (tickNum > 0) {
    System.out.println("窗口 " + Thread.currentThread().getName()
    + " 已售出第 " + tickNum-- + " 张票");
    } else {
    break;
    } }
    try {
    Thread.sleep(100);
    } catch (Exception ex) {
    ex.printStackTrace();
    }
    }
    }
    }
      

  5.   


    非常感谢,请问我是因为什么原因而得不到正确的结果呢,现在初学线程很迷茫,望赐教~
    AtomicInteger是原子变量,用它差不多可以不加锁了解决了部分问题,虽然并不是完全地解决了我的困惑,但也提供了另一种思路,谢谢啦~
      

  6.   


    好奇怪,我原来也锁过this的,但是会tickNum越界,加了if语句后就好了,不知道tickNum这个变量有没有可能单独锁住
      

  7.   


    非常感谢,请问我是因为什么原因而得不到正确的结果呢,现在初学线程很迷茫,望赐教~
    那是因为你的tickNum是可变的,改成下面试试:public class SellTickets
    {
        public static void main(String[] args)
        {
            SellWindow sellWindow = new SellWindow();
            for (int i = 1; i < 4; i++)
            {
                new Thread(sellWindow, String.valueOf(i)).start();
            }
        }
    }
    class SellWindow implements Runnable
    {
        private static final Object o = new Object();
        Integer tickNum = 0;
        @Override
        public void run()
        {
            synchronized (o)
            {
               while(tickNum < 50)
               {            
                   System.out.println("窗口 " + Thread.currentThread().getName() + " 已售出第 " + ++tickNum + " 张票");
                }
            }
        }
    }
      

  8.   


    非常感谢,请问我是因为什么原因而得不到正确的结果呢,现在初学线程很迷茫,望赐教~
    AtomicInteger是原子变量,用它差不多可以不加锁了
    有“先判断后执行”的情况必须加锁。
      

  9.   

    之前写的代码,不过我统计的是剩余票数,稍微改下就行
    package workerpratice;public class TestThread implements Runnable { public int num = 10;
    public int i = 0; // 重写Runnable的方法
    @Override
    public void run() {
    // TODO Auto-generated method stub
    while (true) {
    // 运用同步机制来调用线程,从而有效地防止资源冲突
    synchronized ("") {
    if (num > 0) {
    try {
    Thread.sleep(1000); } catch (Exception e) {
    e.printStackTrace();
    }
    i = --num; System.out.println("当前余票数为:" + i);
    }
    }
    }
    } public static void main(String[] args) {
    TestThread t = new TestThread();
    Thread t1 = new Thread(t);
    Thread t2 = new Thread(t);
    Thread t3 = new Thread(t);
    Thread t4 = new Thread(t);
    t1.start();
    t2.start();
    t3.start();
    t4.start();
    }
    }
      

  10.   


    好奇怪,我原来也锁过this的,但是会tickNum越界,加了if语句后就好了,不知道tickNum这个变量有没有可能单独锁住变量是不能锁住的吧?越界可能把synchronized (this)放在这个位置
    while(tickNum < 50)
            {
                synchronized (this)
                {
    那么并发的话,有可能会越界