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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© SmallRooker 中级黑马   /  2014-8-23 20:51  /  967 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

/*
        同步函数与同步代码块调用的是同一个锁吗?
                调用的不是同一个锁。
        验证步骤如下:
        1.创建一个Demo对象用于执行同步操作 这个类实现Runnable线程扩展接口
        2.创建一个同步代码块用于和同步函数对比。
        3.创建一个同步函数用于验证是否和同步代码块调用的同一个锁。
        4.创建对象并开启线程看输出结果是否实现了同步
*/

class Demo implements Runnable
{
        private int num = 300;
        boolean bn = true;
        Object obj = new Object();
        public void run()
        {
                if(bn)
                {
                        while(true)//定义 无限循环原因 :当num小于等于0时线程还在继续执行。
                        {
                                synchronized(obj)//这里obj是测试代码写进去的对象不同的锁。正确的锁改成this
                                {
                                        if(num>0)
                                        {
                                                //运行同步代码块
                                                try{Thread.sleep(10);}catch(InterruptedException e){}//当运行这个函数的时候让它停一下
                                                System.out.println("线程:"+Thread.currentThread().getName()+"----------obj=="+num);
                                                num--;
                                        }
                                }
                        }
                }
               
                else
                        while(true)
                                show();

                       
        }
        public synchronized void show()//同步函数的锁用的是this所以把上边代码块锁到一个锁里边就不会安全隐患了。
        {
                if(num>0)
                {
                        //运行同步函数
                        try{Thread.sleep(10);}catch(InterruptedException e){}//当运行这个线程的时候让停一下
                        System.out.println("线程:"+Thread.currentThread().getName()+"----------function=="+num);
                        num--;
                }
        }
}
class ThFunLock
{
        public static void main(String[] args)
        {
                Demo t = new Demo();
                //这里让主线程先睡10秒钟
                //作用因为主线程执行的太快 没有等其他线程执行的时候就已经执行过去了。还没有实现
                //切换看不出效果 所以要这样先顶一下 :作用看效果。
               
                Thread Th1 = new Thread(t);
                Thread Th2 = new Thread(t);
                Th1.start();
                //主线程睡一下,然后再把bn变成假
                try{Thread.sleep(10);}catch(InterruptedException e){}
                t.bn = false;
                Th2.start();

                //这样整体运行的结果为最后 出现了零 。如果是卖票系统 现在就出现了零好票。
                //为什么加同步了,还会出现零呢。实现了同步但没有把这两个线程锁定到一个锁里边 。
                //他俩个执行了一个同步代码块,相当于上厕所的时候,去的是同一个厕所,但冲水的时候用
                //不同的水龙头充的,所以也要把这个把这两个线程锁定到一个所里边。
               
        }
}

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马