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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 黄敏 中级黑马   /  2012-8-9 14:38  /  3126 人查看  /  10 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

今天看了毕老师的java多线程教程,遇到一个问题就是想不明白了 求教!
问题 :  synchronized() 同步这个()理必须有对象,毕老师也说什么对线都行 随便写 ,这个对象就起到锁的功能,1,是谁给了这个对象 锁的功能呢?
2,这个对象是怎么判断一个线程进来了就改变这个对象标示位了?

3,一个线程走完同步代码块 ,又是怎么把标示位改变回去了呢?这其中是谁再操作这个对象了呢?


看底下的代码,帮忙解释清楚,现在还晕着呢

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();


        }
}


评分

参与人数 1技术分 +1 收起 理由
张_涛 + 1 新人亮相,赞一个!

查看全部评分

10 个回复

倒序浏览
这个问题没人能解决吗?
回复 使用道具 举报
速来回答,有分奖!
回复 使用道具 举报
这是java虚拟机的运行机制,也是java这门语言的规则:
1.  synchronized(obj),其中的obj对象有锁的功能,这是java语言在有创建synchronized()的时候就给了它这个用法。
2、3.我认为答案都是JVM在其中处理它们。
其实这块没必要那么深究它们,这些都是java语言的运行机制,是创建java语言的人就是这样定义,我们知道用就行了。
纯属个人理解,看看!

评分

参与人数 1技术分 +1 收起 理由
张_涛 + 1 奖励下!

查看全部评分

回复 使用道具 举报
黑马王鹏 发表于 2012-8-9 15:03
这是java虚拟机的运行机制,也是java这门语言的规则:
1.  synchronized(obj),其中的obj对象有锁的功能, ...

我感觉不是,应该是一个类中有这个方法做这个判断吧,创建对线调用方法最判断吧
回复 使用道具 举报
黑马王鹏 发表于 2012-8-9 15:03
这是java虚拟机的运行机制,也是java这门语言的规则:
1.  synchronized(obj),其中的obj对象有锁的功能, ...

其实,第2、3个问题,JVM要实现它们也很简单,我想到的方法就是给他们一个全局的变量flag作为标识符不就可以了么,当有线程的进来了执行资源就改变flag为true,别的线程判断flag为true时就等呗,当线程执行完成了就改变flag为false,让别的线程去执行资源。
JVM也应该是用类似的方法去实现synchronized()上锁的功能。
这已经到了计算机底层的东西了,你还想深究的话,也可以自己去做实验呀!
回复 使用道具 举报
黑马王鹏 发表于 2012-8-9 15:13
其实,第2、3个问题,JVM要实现它们也很简单,我想到的方法就是给他们一个全局的变量flag作为标识符不就 ...

呵呵,好主意,谢了
回复 使用道具 举报
{:soso_e194:}求解,求真相,{:soso_e194:}
1,是谁给了这个对象 锁的功能?
2,这个对象是怎么判断一个线程进来了就改变这个对象标示位了?
3,一个线程走完同步代码块 ,又是怎么把标示位改变回去了呢?这其中是谁再操作这个对象了?

点评

请联系老师更改ID名字,或者在常见问题咨询专版发帖。否则无法加分。  发表于 2012-8-9 15:35
回复 使用道具 举报
本帖最后由 张雪磊 于 2012-8-9 16:28 编辑

我找到了Synchronized和Lock的底层实现方法,但是复制不过来,你们去看看吧http://wenku.baidu.com/view/41480552f01dc281e53af090.html
回复 使用道具 举报
  所有对象都自动含有单一的锁。
  JVM负责跟踪对象被加锁的次数。如果一个对象被解锁,其计数变为0。在任务(线程)第一次给对象加锁的时候,计数变为1。每当这个相同的任务(线程)在此对象上获得锁时,计数会递增。
只有首先获得锁的任务(线程)才能继续获取该对象上的多个锁。
每当任务离开一个synchronized方法,计数递减,当计数为0的时候,锁被完全释放,此时别的任务就可以使用此资源。
当使用同步块时,如果方法下的同步块都同步到一个对象上的锁,则所有的任务(线程)只能互斥的进入这些同步块。
Lock 的锁是通过代码实现的,而 synchronized 是在 JVM 层面上实现的
synchronized 在锁定时如果方法块抛出异常,JVM 会自动将锁释放掉,不会因为出了异常没有释放锁造成线程死锁。但是 Lock 的话就享受不到 JVM 带来自动的功能,出现异常时必须在 finally 将锁释放掉,否则将会引起死锁。


在资源竞争不是很激烈的情况下,偶尔会有同步的情形下,synchronized是很合适的。原因在于,编译程序通常会尽可能的进行优化synchronize,另外可读性非常好,不管用没用过5.0多线程包的程序员都能理解。

ReentrantLock:
ReentrantLock提供了多样化的同步,比如有时间限制的同步,可以被Interrupt的同步(synchronized的同步是不能Interrupt的)等。在资源竞争不激烈的情形下,性能稍微比synchronized差点点。但是当同步非常激烈的时候,synchronized的性能一下子能下降好几十倍。而ReentrantLock确还能维持常态。

Atomic:
和上面的类似,不激烈情况下,性能比synchronized略逊,而激烈的时候,也能维持常态。激烈的时候,Atomic的性能会优于ReentrantLock一倍左右。但是其有一个缺点,就是只能同步一个值,一段代码中只能出现一个Atomic的变量,多于一个同步无效。因为他不能在多个Atomic之间同步。





回复 使用道具 举报
问题已解决
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马