解决方案 »

  1.   

    start之后只是让线程进入runnable状态,等待CPU分配时间片之后才会被执行(也就是执行run方法)
    这里可能是等你把name值改为2之后才被CPU分配到时间片,才执行run方法
    中间有个时间差的
      

  2.   

    你可以测试下:
    在设置name为2前面添加个测试输出语句 
    在2个run方法里面添加个测试输出语句
      

  3.   

     MultiThread multiThread = new MultiThread();
             Thread thread1 = new Thread(multiThread);
             multiThread.setName("1");
             thread1.start();
             Thread.sleep(2000);
             Thread thread2 = new Thread(multiThread);
             multiThread.setName("2");
             thread2.start();
      

  4.   

    主线程里两个子线程 想要明确的让第一个线程先走的话,线程之间最好sleep()一下,你这个情况就是第一个线程刚走到判断那,然后主线程往下走改变Name的值变为2 使第一个线程不走m1,走m2。 现在的代码你多执行几次还是有机会出现m1,m2,但是不稳定。
      

  5.   


    我知道这种情况,即使是把name值改为2之后才被CPU分配到时间片,那结果也应该输出的是
    m2::::2
    m1::::2
    才对呀
      

  6.   

        public void run() {
            if (this.getName().equals("1")) {
                m1();
            }else if(this.getName().equals("2")){
                m2();
            }
    name的值在执行这个之前就改变了 所以都进入m2(),在这之前加锁就行了
      

  7.   

    问题在于LZ的代码用了同一个MultiThread对象来生成2个线程,导致对象MultiThread里面的变量出现同步问题。
    LZ可以试着将代码改成    public static void main(String[] args) {
            MultiThread multiThread = new MultiThread();
            Thread thread1 = new Thread(multiThread);
            multiThread.setName("1");
            thread1.start();
            MultiThread multiThread2 = new MultiThread();
            Thread thread2 = new Thread(multiThread2);
            multiThread2.setName("2");
            thread2.start();
        }就会正常了。
      

  8.   

    楼上加睡眠可以出现不同情况.
    楼主这种情况的出现应该是,主线程执行代码速度很快执行过去(与个人电脑配置有关系),开启了两个线程,那么主线程一瞬间执行完代码,这时候name已经覆盖了上一次的赋值,成为了2,,直到主线程结束后,另外两个线程才抢到执行权.所以两个线程分别抢到执行全的时候,name都等于2,当然两字都是执行m2,name为2了.
    不知道这种表达,楼主能否明白
      

  9.   

    如果两个线程之间没有使用睡眠阻塞,那么在使用的同一个Runnable对象里面的nama变量赋值都为“2”,所以都是执行的m2方法
      

  10.   

    public class Bank implements Runnable{
    private int money = 20000;

    public int getMoney() {
    return money;
    }
    public void setMoney(int money) {
    this.money = money;
    }
    private String matipulate;

    public String getMatipulate() {
    return matipulate;
    }
    public void setMatipulate(String matipulate) {
    this.matipulate = matipulate;
    }
    public void run() {
    if(matipulate.equals("get"))
    getMoney(1000);
    if(matipulate.equals("save"))
    saveMoney(1000);

    }
    private int getMoney(int num){
    this.money -= num;
    System.out.println("from bank get money:" + num);
    System.out.println(getMoney());
    return num;
    }
    private void saveMoney(int num){
    this.money += num;
    System.out.println("to bank save money:" + num);
    System.out.println(getMoney());
    }
    public static void main(String[] args) {
    Bank bank = new Bank();
    Thread t1 = new Thread(bank);
    Thread t2 = new Thread(bank);
    bank.setMatipulate("get");
    t1.start();
    bank.setMatipulate("save");
    t2.start();
    System.out.println(bank.getMoney());

    }}
    楼主运行一下这个程序,多运行几次,你就知道线程之间的执行顺序了。有点类似于多道程序处理机在没有引入进程之前,并发程序的运行会产生间断性、不可再现性和失去封闭性的特点
      

  11.   

    问题在于m1中加了sleep,为什么要在m1中加sleep?等着别的线程将multithread的name值变掉?
    这本来就违背了你的设计初衷吧
      

  12.   

    public class MultiThread implements Runnable {
        private String name;
     
        public String getName() {
            return name;
        }
     
        public void setName(String name) {
            this.name = name;
        }
     
        public void run() {
            if (this.getName().equals("1")) {
                m1();
            }else if(this.getName().equals("2")){
                m2();
            }
        }
     
        private  void m1() {
            System.out.println("m1::::"+this.getName());
        }
     
        private void m2() {
            System.out.println("m2::::"+this.getName());
        }
     
        public static void main(String[] args)  {
            MultiThread multiThread = new MultiThread();
            Thread thread1 = new Thread(multiThread);
            multiThread.setName("1");
            thread1.start();
            try {
    Thread.sleep(500);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
            Thread thread2 = new Thread(multiThread);
            multiThread.setName("2");
            thread2.start();
        }
    }
    m1不存在并发的问题,木有必要用synchronized
      

  13.   

    因为是同一个Runnable,第一个线程虽然调用了start(),但可能还没开始执行,接下来第二个线程又把这个Runable的name改变了,然后两个线程开始执行run方法,这样是不是会出现你的情况呢
      

  14.   

    package com.zken.pkg;public class MultiThread implements Runnable {
    private String name; public String getName() {
    return name;
    } public void setName(String name) {
    this.name = name;
    } public void run() {
    if (this.getName().equals("1")) {
    m1();
    }else if(this.getName().equals("2")){
    m2();
    }
    } private synchronized void m1() {
    try {
    Thread.sleep(1000 * 10);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println("m1::::"+this.getName());
    } private void m2() {
    System.out.println("m2::::"+this.getName());
    } public static void main(String[] args) {
    MultiThread multiThread = new MultiThread();
    Thread thread1 = new Thread(multiThread);
    multiThread.setName("1");
    thread1.start();
    /* try {
    Thread.sleep(100);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }*/
    Thread thread2 = new Thread(multiThread);
    multiThread.setName("2");
    thread2.start();
    System.out.println("~~~~~~~~~~~~~~~~~~~~~~");
    }
    }
    我在代码最后加了一条打印语句,运行了将近上百遍,发现基本每次都是如下结果:
    ~~~~~~~~~~~~~~~~~~~~~~
    m2::::2
    m2::::2
    仅有两次出现如下结果:
    m2::::2
    ~~~~~~~~~~~~~~~~~~~~~~
    m2::::2这可能跟个人电脑配置也有关系,这种结果给人的感觉好像是主线程跑得比子线程要快,所以出现了如上结果
      

  15.   

    感谢大家热情的回答,如有兴趣的话,可以参考下这篇文章:
    http://blog.csdn.net/it_man/article/details/7196645
      

  16.   

    你这个问题需要神牛吗? multiThread.setName("2");执行的时候,前面一个线程没有执行到
    if (this.getName().equals("1")) {如果要研究多线程和并发,可以研究
    wait(),notify(),ThreadPoolExecutor,BlockingQueue,Semaphore,Barrier,Latch,ReentrantLock
      

  17.   

    还有一个问题哈,各位神牛是如何理解java中的sychronized同步和数据库中锁的概念的,我觉得它们之间是很相似的,但我不能系统完整的表达出它们之间的关系,各位神牛有什么高见,请不吝赐教啊~~~~~~~~~~~~~~~~~~~
      

  18.   


    嗯,不好意思啊,本人水平太次请问你是如何理解java中的同步和数据库中锁的机制的??????????????????
      

  19.   


    必须的,高手都在民间,民间的高手都在网上!!!网上的高手都在csdn
      

  20.   


    嗯,好,简单明了,就是线程同步问题,你对主线程和子线程之间的关心有什么独到的见解吗?不妨给大家分享一下哈~~~~~~~~~~~~
    我觉得你这个不是子线程和主线程的问题,只是单纯的两个线程之间的问题。你这里相当于用两个线程操作同一个对象,所以出现的问题。我不知道你要测什么啊,那个如果是要测试是哪个线程在执行哪个方法,可以设置Thread的name。
      

  21.   


    嗯,好,简单明了,就是线程同步问题,你对主线程和子线程之间的关心有什么独到的见解吗?不妨给大家分享一下哈~~~~~~~~~~~~
    我觉得你这个不是子线程和主线程的问题,只是单纯的两个线程之间的问题。你这里相当于用两个线程操作同一个对象,所以出现的问题。我不知道你要测什么啊,那个如果是要测试是哪个线程在执行哪个方法,可以设置Thread的name。怎么可能是两个单纯两个线程之间的关系?!!!那两个子线程都是由主线程main创建的,跟线程之间争抢cpu资源有关,我主要想测试一下线程并发时执行顺序和线程之间的关系问题,以及深入理解一下cpu是分配时间片给线程的。。不过,看了许多网上的文章以及大家积极的回答和帮助,我现在已经理解的差不多了,感谢》》》》