疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java多线程顺序执行


 

可恶的Java多线程,一直没搞懂同步的作用!
   
    一直以为同步的时候只要锁住对象就能顺序执行了:
   
    public class Test {
   
    final static byte[] b = new byte[0];
   
    public static void main(String[] args) {
   
    Test t = new Test();
   
    t.thread.start();
   
    Test t2 = new Test();
   
    t2.thread.start();
   
    }
   
    Thread thread = new Thread(new Runnable() {
   
    @Override
   
    public void run() {
   
    test();
   
    }
   
    });
   
    public void test() {
   
    synchronized (this) {
   
    for (int n = 0; n < 100; n++) {
   
    System.out.println(thread.getName() + ":" + n);
   
    try {
   
    Thread.sleep(1000);
   
    } catch (InterruptedException e) {
   
    e.printStackTrace();
   
    }
   
    }
   
    }
   
    }
   
    }
   
    但是这样是错误的!两个线程还是交替执行!
   
    查阅了很多资料才知道上面这个锁是不正确的,两个线程锁住的this对象不是同一个,所以导致交叉执行。应该修改为:
   
    public class Test {
   
    final static byte[] b = new byte[0];
   
    public static void main(String[] args) {
   
    Test t = new Test();
   
    t.thread.start();
   
    t.test();
   
    }
   
    Thread thread = new Thread(new Runnable() {
   
    @Override
   
    public void run() {
   
    test();
   
    }
   
    });
   
    public void test() {
   
    synchronized (this) {
   
    for (int n = 0; n < 100; n++) {
   
    System.out.println(thread.getName() + ":" + n);
   
    try {
   
    Thread.sleep(1000);
   
    } catch (InterruptedException e) {
   
    e.printStackTrace();
   
    }
   
    }
   
    }
   
    }
   
    }
   
    这样的确就是顺序执行了,因为函数锁住的this对象是同一个,如果去除线程同步当然就会交叉执行啦。
   
    但是我还有点不明白的是第一个例子错误的原因是其锁住的对象不是同一个,但是如果我把this改为一个全局静态常量还是不正确!理论上全局静态常量整个运行周期内存中只会有一个对象阿!不明白为什么还是不行!希望有高手可以解答。
   
    其实我们用到同步多半是为了让线程顺序执行,比如在做Android开发的时候,我们通常希望前台显示一个进度框,后台线程去执行下载动作,下载完之后前台线程在执行余下操作如界面显示。
   
    这个时候其实可以使用线程的join()!
   
    oin方法大家可以查下api,它的意思是等待当前线程执行完后执行完毕才执行其他线程。也就是说如果一个类中有这样一个代码段:
   
    thread1.start();
   
    thread2.start();
   
    thread1.join();
   
    thread2.join();
   
    do something 1;
   
    do something 2;
   
    那么这段代码会等待两个线程执行完毕后再执行 do something 1 和 do something 2,注意:必须先启动所有线程,再join.如果启动一个就join一个,结果是什么?对,那就会是等待thread1执行完再执行thread2,再执行后续代码。