我的一个java多线程程序,每次执行结果,有时候不一样,我在网上搜索到:
我猜你的电脑应该也是多核的。单核的cpu在处理多线程时每次只能执行一跳指令,也就是说无论你的程序有多少个线程,每一时刻执行的也只是一个线程里的代码,cpu会轮流给每个线程分配时间片,时间片分配到哪个线程头上,哪个线程里的代码就执行。但是多核cpu就不一样了,他可以同时执行多个线程里的代码,这才是真正的“多线程”。所以你那段程序,在单核的电脑上跑应该是没有问题的,但是在多核cpu的电脑上出现的结果就会有很大的随机性。 
就你贴的那张图来说,左边的运行时恰好是这样的,首先cpu1执行你主线程里的代码 在终端输出Now another thread has been created. ID =,但是由于多个cpu是同时进行的,而这时cpu2已经开始执行ThreadProc里的代码,也要开始向终端输出字符,而你的屏幕只有一个,恰好这时cpu1的时间片被移走了,所以cpu2开始执行ThreadProc里的代码向屏幕上输出,直到打完I am from a thread 17后,恰好cpu2的时间片被移走了,这时cpu1接着向屏幕打dwThreadId的值,这就出现了4660.接着又是cpu2执行完ThreadProc中剩余的代码又打了几行。 
右边的这个程序运行时,恰好就是cpu1执行主线程代码输出完后,cpu2再执行线程函数中代码,符合你的预期。 
但是,关键问题在于,你无法预测每个cpu的时间片分配。所以,要得到你想要的输出结果就属于随机事件了。 
对与多核cpu 上的程序同步问题,最好不要用信号量,互斥量,事件对象,因为它们都属于内核对象,都是对一个cpu而言的。其他的cpu根本不会理睬你设置的这些东西。另外你的WaitForSingleObject (hThread, INFINITE); 也是在一个cpu里等待线程函数返回,对cpu2没有任何作用。
总结出来,就是说.java的简单的多线程程序在双核上运行,结果会和理论不一样??

解决方案 »

  1.   

    多线程和CPU核数(除非线程数=核数)没有关系,JAVA多线程运行的机制是虚拟CPU,也就是划分时间片,划分的时间片可以看做是单个CPU在执行任务,因为时间片很短,所以每个时间片可能执行的线程就不确定拉,所以程序运行就可能出现多种不同的运行结果
      

  2.   

    那就是说,这个程序:public class ThreadTest implements Runnable
    {
    public static int a = 0; public void run()
    {
    for (int k = 0; k < 5; k++) 
    {
    a = a + 1;
    }
    } public static void main(String[] args)

    Runnable r = new ThreadTest(); 
    Thread t = new Thread(r); 
    t.start(); 
    System.out.println("first " + a); 
    }
    }理论上是输出 first 0
    但是有时候他输出的是 first 5
    这个跟双核没有关系?  在单核上,也有可能出现这种情况?
      

  3.   

    多线程和CPU核数(除非线程数=核数)没有关系,
    这句话是说,如果线程数=核数的话,又会怎么样?
    我电脑是双核
    这个程序 线程数是多少?   二者相等不? 如果是相等的话,那我下面这个程序在单核电脑上运行,会出现理论值和实际结果不一样的情况不?
    class Semaphore
    {}public class AccountThread2 extends Thread
    {
    Account account;
    Semaphore semaphore;
    int delay;
    public AccountThread2(Account account,int delay,Semaphore semaphore)
    {
    this.account = account;
    this.delay = delay;
    this.semaphore = semaphore;
    }

    public void run()
    {
    System.out.println(AccountThread2.currentThread() + "  1");
    synchronized (semaphore) 
    {
    if(account.balance >= 100)
    {
    try
    {
    System.out.println(AccountThread2.currentThread() + "  2");
    sleep(delay);
    System.out.println(AccountThread2.currentThread() + "  3");
    account.balance = account.balance - 100;
    System.out.println("withdraw 100 successful!");
    }
    catch(InterruptedException e)
    {}
    }
    else
    System.out.println("withdraw failed!");
    }
    }

    public static void main(String[] args)
    {
    Account account = new Account(100);
    Semaphore semaphore = new Semaphore();
    AccountThread2 accountThread21 = new AccountThread2(account,1000,semaphore);
    AccountThread2 accountThread22 = new AccountThread2(account,0,semaphore);

    accountThread21.start();
    accountThread22.start();
    }
    }
      

  4.   

    线程获得CPU时间片的问题是操作系统决定的,别的不清楚,Windows是抢占式的。两个优先级别相同的线程长时间运行是没有办法保障谁先谁后的,除非有同步和原子操作等作为保障。即便是线程a的优先级高于b,也不能保证完全运行完a之后再运行b。
      

  5.   

    多线程和CPU单核还是双核没关系!
    狂顶!