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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 尹善波 中级黑马   /  2012-7-3 11:14  /  2043 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

毕老师的经典例子:

class Ticket implements Runnable
{
private  int tick = 100;
Object obj = new Object();
boolean flag = true;
public  void run()
{
   if(flag)
     {
  while(true)
   {
   synchronized(this)//同步与所谓的“锁”的原理是什么
    {
      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()//this
{
    if(tick>0)
      {
  try{Thread.sleep(10);}catch(Exception e){}
  System.out.println(Thread.currentThread().getName()+"....show.... : "+ tick--);
             }
}
}
class  ThisLockDemo
{
public static void main(String[] args)    //请分析下主函数中的执行顺序,以及各线程的执行原理和切换方式,毕老师说的主线程
                                                 //和其他线程线程有没有执行上的优先顺序
{
  Ticket t = new Ticket();
  Thread t1 = new Thread(t);
  Thread t2 = new Thread(t);
  t1.start();
  try{Thread.sleep(10);}catch(Exception e){}//特别是这一部分的执行步骤
  t.flag = false;
  t2.start();

}
}

2 个回复

倒序浏览
class Ticket implements Runnable
{
private  int tick = 100;
Object obj = new Object();
boolean flag = true;
public  void run()
{
    if(flag)//条件为真,
    {
                        while(true)//t1线程始终在这个循环里待着,死循环
                         {
                                 synchronized(this)//这里用的是this锁
                                {
                                                if(tick>0)
                                         {
                                                          try{Thread.sleep(10);}catch(Exception e){}
                                                System.out.println(Thread.currentThread().getName()+"....code : "+ tick--);
                                         }
                                 }
                        }
      }
    else
     while(true)//t2线程始终在执行这一句,while true。
      show();
}
public synchronized void show()//这是同步代码快,也是用的this锁     和上面是一个锁,所以就同步了。
{
     if(tick>0)
       {
   try{Thread.sleep(10);}catch(Exception e){}
   System.out.println(Thread.currentThread().getName()+"....show.... : "+ tick--);
              }
}
}
class  ThisLockDemo
{
public static void main(String[] args)    //请分析下主函数中的执行顺序,以及各线程的执行原理和切换方式,毕老师说的主线程
                                                  //和其他线程线程有没有执行上的优先顺序
{
   Ticket t = new Ticket();
   Thread t1 = new Thread(t);
   Thread t2 = new Thread(t);//1,创建t1,t2两个线程,将t作为参数传入其中
   t1.start();//开启t1线程
   try{Thread.sleep(10);}catch(Exception e){}//主线程读到这里。睡了10毫秒。。。
   t.flag = false;//改变t的标记,让上面的if判断条件为假,判断是为假了,可是判断是只执行一次的
                                        //里面是while(true)循环。。。所以t1会一直在while里循环着。
   t2.start();//开启t2线程,由于if判断为false,所以t2直接走else,t1,t2,资源是共享的。

}
}

评分

参与人数 1技术分 +1 收起 理由
刘蕴学 + 1

查看全部评分

回复 使用道具 举报
本帖最后由 feigecal 于 2012-7-3 15:07 编辑

所谓锁就好比一个房间,你进来后把门锁上,别的人就不能进来,你把你要做的事情做完了,把锁打开出去后别人才能进来。这里的人就好比是线程,一个线程判断锁后进去后,就会锁上,另一个线程就进不去,防止一个线程在进去后判断tick大于0后还没执行输出语句没有改变if的条件的时候另一个线程也进来,就会造成tick大于0被两个线程都判断过,就会出现0和负数的结果。再说主函数的顺序吧,先new出一个资源的对象,然后把对象做为创建线程的参数传进去,来创建同资源的两个线程t1和t2,先开启了t1线程,主线程睡了10毫秒然后读下一个语句,就是把标记flag改为false,然后再开启线程t2,因为在之前已经把标记改了,所以线程t2是进不以if的执行语句的,也就进不了同步代码块,同时线程t1也在循环里不能出来,因为是while(true),所以线程t2直接执行else,执行同步函数,因为同步函数的锁是对象,就是this,所以同步代码块的锁也得是this才能同步。然后他们就相当于是两个窗口售票,各执行各的,但用的是同一资源,也解决了安全问题。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马