A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© zhouxp3323 黑马帝   /  2012-3-18 09:08  /  3395 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

class Ticket2 implements Runnable{
        private int tick=1;
        boolean flag = true;
        public void run(){
                if(flag){
                                synchronized(this){
                                        while(tick <= 100){
                                                try {
                                                        Thread.sleep(10);
                                                } catch (InterruptedException e) {
                                                        e.printStackTrace();
                                                }
                                                System.out.println(Thread.currentThread().getName()+"...code..."+ tick++);
                                        }
                                }
                        }
                else
                        show();
        }
       
        public synchronized void show(){
                while(tick <= 300){
                        System.out.println(Thread.currentThread().getName()+"...show..."+ tick++);
                }
        }
}

public class TicketLockDemo {
        public static void main(String[] args) {
                Ticket2 t = new Ticket2();
                Thread t1 = new Thread(t);
                Thread t2 = new Thread(t);
               
                t1.start();
                try {
                        Thread.sleep(10);
                } catch (InterruptedException e) {
                        e.printStackTrace();
                }
                t.flag = false;
                t2.start();
        }
}
每次的结果都是先打印Thread-0,1到100,然后就是Thread-1,101到300,为什么不是同步呢,程序有什么问题吗,谁能帮我分析下吗?

9 个回复

倒序浏览
到底想要什么效果呢?
回复 使用道具 举报
sleep()函数是Thread类的静态函数,不涉及到线程间同步概念,仅仅为了让一个线程自身获得一段沉睡时间。sleep可以在任何地方使用。
wait函数是object类的函数,要解决的问题是线程间的同步,该过程包含了同步锁的获取和释放,调用wait方法将会将调用者的线程挂起,直到其他线程调用同一个对象的notify方法才会重新激活调用者。
public static void sleep(long millis)
                  throws InterruptedException在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。该线程不丢失任何监视器的所属权。

点评

哦,有点明白了  发表于 2012-3-18 18:26

评分

参与人数 1技术分 +1 收起 理由
房宝彬 + 1

查看全部评分

回复 使用道具 举报
因为你同步函数和同步代码块用了同一个锁,当第一个线程进去后获得锁开始打印,这时候第二个线程就得不到锁了只能等待,要达到想要的结果就是把同步代码块那里的锁换一下就行了,比如随便new个object

评分

参与人数 1技术分 +1 收起 理由
房宝彬 + 1

查看全部评分

回复 使用道具 举报
张锐 发表于 2012-3-18 17:36
因为你同步函数和同步代码块用了同一个锁,当第一个线程进去后获得锁开始打印,这时候第二个线程就得不到锁 ...

楼主说的果然是,刚刚把锁换了下,果然就同步了,:kiss:!
回复 使用道具 举报
我有个疑问,this锁和Object锁有什么区别?同步锁和异步锁有什么区别呢?
回复 使用道具 举报
蒙武辉 发表于 2012-3-18 18:45
我有个疑问,this锁和Object锁有什么区别?同步锁和异步锁有什么区别呢?

晕,你怎么不去单独发个帖子啊,那样可能会有积分啊!同步锁就是比如说有两个代码块(或者方法),当一个线程进入一个代码块的时候,可能在那处于冻结状态的时候,由于这两个代码块持有相同的锁,所以别的线程想进入另外一个代码块执行的时候,就必须先等第一个线程执行完后,释放了锁,别的线程才有可能进入。
回复 使用道具 举报
OMG 中级黑马 2012-3-19 11:08:17
8#
哥们,你的代码,我有疑问:
为什么你要用while(while(tick <= 100))而不用if(if (tick <= 100)?
如果你是为了线程安全那就应该使用同一个锁(this),但是线程安全了,就会执行while循环,直到循环结束;
如果你要打破while循环,那就使用两个锁,用了两个锁就不安全了,如果不安全,那就没有必要加同步了;
所以,反过来,你应该把while改成if,而不是把this改成obj;
回复 使用道具 举报
当多个对象访问被synchronized修饰的类时,只能有一个对象可以访问,第二个对象等待第一个对象访问结束后才能访问。相当于给方法加了一把锁。
你把同步锁synchronized拿掉,对象自然就可以同时访问了。
回复 使用道具 举报
OMG 发表于 2012-3-19 11:08
哥们,你的代码,我有疑问:
为什么你要用while(while(tick

呵呵,我也发现了,后来我改了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马