注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

罔少年

QQ 332256483

 
 
 

日志

 
 

java 同步锁 synchronized  

2015-04-14 16:47:49|  分类: java |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
cpu分给每个线程的时间片是随机的并且好多情况下多个线程共用一个资源
比如卖火车票,火车票比作资源,窗口比作线程。1000张火车票如果在一个时间点上,a,b,c 3个窗口(线程)同时卖票(使用这个资源),那一定会出相同的座位的票。

class TicketSouce implements Runnable
{
    //票的总数
    private int ticket=10;
    public void run()
    {
        for(int i=1;i<50;i++)
        {
            if(ticket>0)
            {
                //休眠1s秒中,为了使效果更明显,否则可能出不了效果
                try {
                    Thread.sleep(1000);
                }
 catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println(Thread.currentThread().getName()+"号窗口卖出"+this.ticket--+"号票");
            }

        }

    }

}

public class Test {
    public static void main(String args[])
    {
        TicketSouce mt=new TicketSouce();
        //基于火车票创建三个窗口
        new Thread(mt,"a").start();

        new Thread(mt,"b").start();
        new Thread(mt,"c").start();
   }
 
}
 

输出结果:7号票出了2次
java 同步锁 synchronized - 我是小黄人 - lanaiver6291的博客
 
分析原因:
a线程取出7号票以后,ticket还没来的及减1b线程就取出了ticket此时ticket还等于7
解决方式:
出现了上述情况怎样改变呢,我们可以这样做:当一个线程要使用火车票这个资源时,我们就交给它一把锁,等它把事情做完后在把锁给另一个要用这个资源的线程。这样就不会出现上述情况。 实现这个锁的功能就需要用到synchronized这个关键字。

synchronized这个关键字有两种用法1、放方法名前形成同步方法;2、放在块前构成同步块。

//1、使用同步方法将上面的例子该为:

class TicketSouce implements Runnable
{
    //票的总数
    private int ticket=10;
    public void run()
    {
        for(int i=1;i<50;i++)
        {
            try {
                //休眠1s秒中,为了使效果更明显,否则可能出不了效果
                Thread.sleep(1000);
            }
 catch (InterruptedException e) {
                e.printStackTrace();
            }

            this.sale();
        }

    }

    public synchronized void sale()
    {
            if(ticket>0)
            {
                System.out.println(Thread.currentThread().getName()+"号窗口卖出"+this.ticket--+"号票");
            }

    }

}

public class Test {
    public static void main(String args[])
    {
        TicketSouce mt=new TicketSouce();

        //基于火车票创建三个窗口
        new Thread(mt,"a").start();
        new Thread(mt,"b").start();
        new Thread(mt,"c").start();
    }
 

}
 

//2、使用同步块修改上面的例子:

class TicketSouce implements Runnable
{
    //票的总数
    private int ticket=10;
    public void run()
    {
        for(int i=1;i<50;i++)
        {

synchronized(this){
            if(ticket>0)
            {
                //休眠1s秒中,为了使效果更明显,否则可能出不了效果
                try {
                    Thread.sleep(1000);
                }
 catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println(Thread.currentThread().getName()+"号窗口卖出"+this.ticket--+"号票");
            }

}


        }

    }

}

public class Test {
    public static void main(String args[])
    {
        TicketSouce mt=new TicketSouce();
        //基于火车票创建三个窗口
        new Thread(mt,"a").start();

        new Thread(mt,"b").start();
        new Thread(mt,"c").start();
   }
 
}
 

载自:http://www.blogjava.net/tscfengkui/archive/2010/11/10/337709.html?opt=admin
  评论这张
 
阅读(47)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018