解决方案 »

  1.   

    个人认为单核cpu不会出现不正常的情况,多核cpu会出现不正常情况。
    原因:
    1、单核cpu执行多线程实际上是来回切换执行线程(1线程执行了一次,切换到2线程执行,甚至于连续执行某个线程),由于是单核,所以第二次执行的线程必然等到第一次完成后才有机会执行(必然出现时间差)。
    2、多核cpu,cpu1执行的时候,cpu2同样可以执行,那么这时就可能出现同时操作tickets的情况,就是你打印出来的“窗口2正在出售第100张票”说的不对望指正,个人对cpu如何执行指令没有研究过。
      

  2.   

    我觉得,把票数定义在线程里是不对的,这样子不就是各个线程启动后,处理的都是各自的票数吗?
    改成下面这样,放在主线程里定义,就不会出错。
    class MyThread extends Thread {
    private int num;
    public MyThread(int num){this.num=num;}
    @Override
    public void run() {
    while(num>0) 

    System.out.println(getName() + "正在出售第" + (num--) + "张票");

    }
    }
    public class Test2 {
    public static void main(String[] args) {
    final int num=100;
    MyThread my1 = new MyThread(num);
    MyThread my2 = new MyThread(num);
    my1.setName("窗口1");
    my2.setName("窗口2");
    my1.start();
    my2.start(); }
    }
      

  3.   

    第一段代码:
    你只有两个线程,运行哪一个线程是JVM说了算的,两个线程是交替运行的,之所以看起来有的时候没有问题是因为你的线程的数量太少了,如果你的线程多一些,一定会不按照顺序依次执行的现象出现第二段代码:
    你在每一个SellTicket里面都有100张票,相当于每个窗口都给了100张票,窗口间谁先卖谁后卖会乱,但是每个窗口自己卖票的顺序一定是从100到1递减的,所以没有你认为的混乱的问题第一个回复:
    你的理解是错误的,JVM相当于是一个虚拟机,JVM里面运行的代码和计算机有几个核是没有关系的
      

  4.   

    多线程同时访问同一个全局变量,当然会线程安全的问题了。
    public class Test extends Thread{
    private static int tickets = 100;

    private String name;

    public Test(String name){
    this.name=name;
    }

    private static synchronized int sellOneTicket(){
    return tickets--;
    }

    private static boolean haveTicket(){
    boolean b = false;
    if(tickets>0){
    b=true;
    }
    return b;
    }

    @Override
    public void run() {
    while(Test.haveTicket()){
    System.out.println(this.name + "正在出售第" + sellOneTicket() + "张票");
    }
    } //Main方法
    public static void main(String[] args){
    Test t1 = new Test("窗口1");
    Test t2 = new Test("窗口2");
    t1.start();
    t2.start();
    }
    }
    运行结果:
    窗口1正在出售第100张票
    窗口1正在出售第99张票
    窗口1正在出售第98张票
    窗口1正在出售第97张票
    窗口1正在出售第95张票
    窗口2正在出售第96张票
    窗口1正在出售第94张票
    窗口2正在出售第93张票
    窗口1正在出售第92张票
    窗口2正在出售第91张票
    窗口1正在出售第90张票
    窗口2正在出售第89张票
    窗口1正在出售第88张票
    窗口2正在出售第87张票
    窗口1正在出售第86张票
    窗口2正在出售第85张票
    窗口1正在出售第84张票
    窗口2正在出售第83张票本人I7处理器 4核。
      

  5.   

    第一个问题,访问全局变量线程不安全,出现原因是因为,当线程1执行ticket=100时,在没有真正执行后面的打印部分之前,ticket仍然等于100,此时cpu切换到线程2,它看到的ticket也等于100,因此会出现你说的问题,只要锁同步就行第二个问题,就是你自己说的,他们三个在同卖那个ticket,cpu操作肯定是原子性的望给分啊
      

  6.   

    一句java的代码对cpu来说不是只执行一步,例如a = b--;
    对cpu来说就是把b的值 取出来——然后给a——把a存进去——把b-1——再把b存进去。没记错应该是分这几步。中间没有锁定之类的是随时都有可能断掉的。
      

  7.   

    http://goobbe.com/questions/213242/java-relationship-between-threads-and-cpus
      

  8.   

    用队列,线程安全,初始化长度为100,取出后长度减少,当返回null时,表示票卖完了,如果中间抛异常了还可以把对象加到队列中。
    private static BlockingQueue<对象> queue = new ArrayBlockingQueue<对象>(100);
      

  9.   

    对于第一个问题应该System.out.println操作属于I/O操作,会花费大量的时间,所以导致了你所看到的只是偶尔遇到两个窗口卖相同票的情况,试试将输出先缓存,在线程结束后一次性输出看看。(没做验证请见谅)