黑马程序员技术交流社区

标题: 关于多线程 synchronized 上锁的问题 [打印本页]

作者: o火o把o    时间: 2011-9-27 10:31
标题: 关于多线程 synchronized 上锁的问题
针对毕老师JAVA基础第10天第12个视频请教大家。
为什么把上锁代码块单独拿出来定义函数,然后再调用这个函数show()就可以让多线程启动,而不是多线程下单线程执行。
代码如下:
class Ticket implements Runnable
{
        private static int tick=1;
        public void run()
        {
                while(true)
                {
                        show();
                }
        }
        public synchronized void show()
        {
                        if (tick<=100)
                        {
                                try
                                {Thread.sleep(10);}catch (Exception e){}
                                System.out.println(Thread.currentThread().getName()+"   sale:"+tick++);
                        }
        }
}
class  TickerDemo
{
        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();
        }
}
作者: 匿名    时间: 2011-9-27 10:52
同步   就是要控制这个对象   的某个方法  或是对此对象进行操作时   在预定的一系列操作未完成时  不运行 其他线程操作此对象

解决这个问题的方法就是同步锁,,同步锁   锁的永远是对象

在对象中有2个方法  这个是直接控制对象锁的
wait()  通知其他线程 我要锁这个对象了
notify() 通知其他线程   我解锁了这个对象
作者: 匿名    时间: 2011-9-27 11:40
你是说毕老师的视频看得不是很明白吧,原来的代码是这样的
public synchronized  void run()
        {
                while(true)
                {
                       if (tick<=100)
                        {
                                try
                                {Thread.sleep(10);}catch (Exception e){}
                                System.out.println(Thread.currentThread().getName()+"   sale:"+tick++);
                        }
                }
        }

后来的代码改成你那个样子
public void run()
        {
                while(true)
                {
                        show();
                }
        }
        public synchronized void show()
        {
                        if (tick<=100)
                        {
                                try
                                {Thread.sleep(10);}catch (Exception e){}
                                System.out.println(Thread.currentThread().getName()+"   sale:"+tick++);
                        }
        }
原来的同步代码函数是run方法,所以当有一个线程1进入run方法以后,别的线程都不能再进去,只能在run方法外部等待,而run方法里面有一个while(true)循环,所以哪怕是线程1休眠了也必须等待线程1把while循环里面的代码都运行完以后,别的线程才能进入run方法。而当线程1跑完run方法以后,别的线程进入到while循环,也不能满足if语句进行输出了,所以看起来好像是只有一个线程在运行,其实一直都是多线程的。
而当同步函数是show方法以后呢,锁就在show方法上了,别的线程都可以进入while循环,也可以进行if语句判断,自然也就多个线程都能实现输出了,看起来就是多个线程都能执行输出代码块。
这个例子毕老师主要是告诉我们那些代码需要同步,那些不需要
作者: 匿名    时间: 2011-9-27 12:26
标题: 回复 藤椅 的帖子
public synchronized void show()
        {
                        if (tick<=100)
                        {
                                try
                                {Thread.sleep(10);}catch (Exception e){}
                                System.out.println(Thread.currentThread().getName()+"   sale:"+tick++);
                        }
        }
别的线程的确可以进入while循环,但是show方法包含了 if 判断语句,既然是给show上的锁,别的线程怎么执行 if 判断,以及下面的代码呢?
作者: 匿名    时间: 2011-9-27 12:26
而且你应该注意,线程休眠时,用sleep才不会释放锁,如果你用wait就会释放锁
作者: 匿名    时间: 2011-9-27 12:29
上面是我口误,所有线程都可以进入while循环,但是不能进入if语句块
作者: 匿名    时间: 2011-9-27 12:31
那你也说了,它既然可以进入while循环,所以就有可能会有线程一直在show方法外等待线程1释放show的锁,当线程1跑完show方法后,别的线程就可以进入show方法了
作者: 匿名    时间: 2011-9-27 13:06
明白了,多谢!
我误以为show方法中有循环,以为只有某线程输出完1-100之后才能出来。
作者: 匿名    时间: 2011-9-27 13:21
呵呵,之所以使用锁机制是因为多个线程在操作共享资源且有多条操作共享资源的代码,这样就可能造成数据的隐患,例如当多个人买火车票时当一个人刚好卖到最后一张票而这时另外一个人也卖这张票,那么就有可能造成-1票号的可能。所以为了数据的安全就有了锁,锁的作用就是让在一个时间段对于多条执行共享资源的语句只能用一个线程执行完,在执行的过程中其他的线程是不可以参与的。把上锁代码块单独拿出来定义函数就是为了让这个代码块在一段时间内只能由一个线程执行,例如线程一和线程二都要执行,但线程一先抢到锁,这样就只有等到线程一执行完了函数中的代码块之后线程二才可以执行这个函数中的代码块(当然只是有可能,因为其他线程可能又抢到了执行权)




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2