你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:技术专栏 / Java专栏
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(); 
            } 
            } 
        } 
    } 

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对象不是同一个,所以导致交叉执行。应该修改为:


[java]
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(); 
            } 
            } 
        } 
 
    } 

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,再执行后续代码。

  推荐精品文章

·2024年12月目录 
·2024年11月目录 
·2024年10月目录 
·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089