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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 李志广 中级黑马   /  2012-7-24 10:07  /  2617 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 007lzg 于 2012-7-24 12:37 编辑

class Ticket implements Runnable
{
        private  int tick = 1000;
        Object obj = new Object();
        public void run()
        {
                while(true)
                {
                        synchronized(obj)  //运用同步代码块
                        {
                                if(tick>0)
                                {
                                        try{Thread.sleep(10);}catch(Exception e){}
                                        System.out.println(Thread.currentThread().getName()+"....sale : "+ tick--);
                                }
                        }
                }
        }
}


class  TicketDemo2
{
        public static void main(String[] args)
        {

                Ticket t = new Ticket();

                Thread t1 = new Thread(t);
                Thread t2 = new Thread(t);
                Thread t3 = new Thread(t);
                Thread t4 = new Thread(t);
                t1.start();
                t2.start();
                t3.start();
                t4.start();


        }
}

==============================================
class Ticket implements Runnable
{
        private  int tick = 1000;
        Object obj = new Object();
        public void run()
        {
                while(true)
                {
                        show();               
                }
        }
        public synchronized void show()  //运用同步函数
                {
                    if(tick>0)
                                {
                                        try{Thread.sleep(10);}catch(Exception e){}
                                        System.out.println(Thread.currentThread().getName()+"....sale : "+ tick--);
                                }
                }
}


class  TicketDemo2
{
        public static void main(String[] args)
        {

                Ticket t = new Ticket();

                Thread t1 = new Thread(t);
                Thread t2 = new Thread(t);
                Thread t3 = new Thread(t);
                Thread t4 = new Thread(t);
                t1.start();
                t2.start();
                t3.start();
                t4.start();

        }
}


毕老师在讲解售票的例子的时候,分别用同步代码块和同步函数进行讲些这是事例!
我不明白的是,不是不所有的同步代码块都能转换为同步函数?同步代码块和同步函数哪一个的效率会更高一些呢?
在实际的开发中运用哪一种好呢?





评分

参与人数 1技术分 +1 收起 理由
田向向 + 1 只要努力,一切都会有的

查看全部评分

7 个回复

倒序浏览
转:同步方法:同步方法是指进入该方法时需要获取this对象的同步锁,在方法上使用synchronized关键字,使用this对象作为锁,也就是使用了当前对象,因为锁住了方法,所以相对于代码块来说效率相对较低。

同步代码块:可以指定需要获取哪个对象的同步锁,使用synchronized的代码块同样需要锁,但他的锁可以是任意对象,考虑到安全问题,一般还是使用同一个对象,相对来说效率较高。
在jdk1.5后,用lock锁取代了synchronized,个人理解也就是对同步代码块做了修改,并没有提供对同步方法的修改,主要还是效率问题吧。
大家共同学习争取进入吧
你看一下这帖子吧http://bbs.itheima.com/thread-13365-1-1.html
回复 使用道具 举报
同步的原理:其实就是将需要同步的代码进行封装,并在该代码上加了一个锁。
同步的好处:解决了多线程的安全问题。
同步的弊端:会降低性能。

同步的前提:必须要保证在同步中有多个线程。因为同步中只有一个线程该同步是没有意义的。
            必须要保证多个线程在同步中使用的是同一个锁。
            必须保证多个线程使用的锁是同一个,这时才成为多个线程被同步了。

同步有两种表现形式:一种就是同步代码块。同步代码块中的锁可以是任意的对象,用Object obj = new Object();可以作为同步代码块中的锁。
                    synchronized(对象)  //对象可以使任意的对象。
{
需要被同步的语句。
}
   
  另一种就是同步函数。就是在函数中加入同步代码块的关键字synchronized,这样就能使该函数变为同步函数。
              函数肯定被对象调用,代表调用函数对象的引用就是this。也就是说同步函数使用的锁this
同步函数和同步代码块有什么区别呢?
1、同步函数比同步代码块写法简单。
2、同步函数使用的锁是this。同步代码块使用的锁是任意指定的对象。
   建议开发时,使用同步代码块,尤其是需要不同锁时。

以上是JDK1.5之前使用同步代码块和同步函数来解决多线程中的安全性问题。
但在JDK1.5中,JDK出现了新的借口和类那就是Lock和Condition。
Lock:比同步函数和同步代码块要好。
分析发现:同步函数还是同步代码块所做的都是隐式的锁操作。
同步函数或者同步代码块使用的锁和监视器是同一个。
Lock借口:是将锁进行单独对象的封装。而且提供了对锁对象很多功能
比如:lock()获取锁,unlock()释放锁。Lock对锁的操作都是显示的。
所以它的出现要比同步函数或者同步代码块明确的多,更符合面向对象的思想。
简单一句话:Lock借口的出现替代了同步(函数和代码块)。
原来在同步中,锁和监视器是同一个对象(在同步里)。
现在,升级后,锁是一个单独的对象。而且将监视器的方法也单独封装到了一个对象中, 这个对象就是升级后的Condition
升级后,都进行了单独的封装,锁被封装成了Lock对象,监视器方法被封装到了 Condition对象(监视器)中。
说白了:Lock替代了同步,Condition代替了Objcet中的监视器方法。
Condition中提供了监视器的方法:await().singal().signalAl();
如何让锁和监视器产生联系呢?
直接通过Lock接口中newCondition()方法就可以获取到绑定到该Lock对象上的监视 器对象Condition


以上是我在学习过程中总结的笔记,希望多楼主有用!{:soso__8961432591078930798_3:}

评分

参与人数 1技术分 +1 收起 理由
田向向 + 1 赞一个!

查看全部评分

回复 使用道具 举报
同步函数是指进入该方法时需要获取this对象的同步锁;同步代码块可以指定需要获取哪个对象的同步锁,对象必须是不为null的对象
同步代码快效率高于同步函数。因为同步函数,作用范围大,所以效率低
回复 使用道具 举报
曹俊 发表于 2012-7-24 10:37
同步的原理:其实就是将需要同步的代码进行封装,并在该代码上加了一个锁。
同步的好处:解决了多线程的安 ...

:)多谢!
回复 使用道具 举报
java中每个对象都有同步锁,同步方法是指进入该方法时需要获取this对象的同步锁,而同步代码块则是可以指定需要获取哪个对象的同步锁,以下代码实际上一个效果:
synchronized void t(){}
void t(){
synchronized(this){
}
}
同步代码块可以用如下方式来使用:
void t(){
synchronized(lockObject){}
}
其中lockObject可以为任何不为null值的对象
回复 使用道具 举报
蓝迪 初级黑马 2012-7-24 11:24:09
7#
当函数中只有一条语句时,并且此语句需要同步,则使用同步函数更方便一些
当函数中有多条语句,而只有其中几条是操作到共享数据,需要进行同步,则选择同步代码块
回复 使用道具 举报
蓝迪 初级黑马 2012-7-24 11:28:29
8#
比如
public void run()
        {
                if (flag)
                {
               
                        while(true)
                        {
                                synchronized (Ticket.class)//操作tick共享数据,所以需要同步进行,但是run函数中有else语句,调用show方法,不需要同步,所以使用同步代码块
                                {
                                        if (tick>0)
                                        {
                                                try{Thread.sleep(10);}
                                                catch(Exception e)
                                                {}
                                                System.out.println(Thread.currentThread().getName()+"....code : "+tick--);
                                        }
                                }
                        }
                }
                else
                        while (true)
                        {
                                show();
                        }
               
        }
        public synchronized void show()//函数中只有一条语句,且操作了共享数据tick,所以使用同步函数
        {
                if (tick>0)
                {
                                        try{Thread.sleep(10);}
                                        catch(Exception e)
                                        {}
                                        System.out.println(Thread.currentThread().getName()+"....show.... : "+tick--);
                }
        }
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马