测试是我职业生涯中最喜欢的工作,也希望自己在这个空间里每天进步一点点,改善自己,提高自己。

第五课-多线程同步问题

上一篇 / 下一篇  2008-07-01 14:59:26 / 个人分类:JAVA

多线程同步问题
*什么是线程安全
*同步代码块
*同步函数
*代码块与函数间的同步
*死锁问题
45分钟
刚才的程序有一个意外就是tickets的值
还有一种情况是tickets=0的情况时也会出现答应
class Threaddemo1
{
public static viod main(String [] args//main方法是在线程上进行的
    {
    TestThread tt= new TestThread ()

new Thread(tt).start();
new Thread(tt).start();
new Thread(tt).start();
new Thread(tt).start();//接受tt对象,然后创建多个线程
     }
}
class TestTread  implments Runnable//集成接口 runnable类灵活的多
{   int tickets = 100;
   public void run()
    {
     while (true)
       {
        if (tichests>0)
{   try{Tread.sleep(10);}catch(Excetption e){}_
         system.out.println("run:"+Thread.currentThread().getName()+"is saling ticket"+ tickets
--)//
}
       }
     }
}
就打印除了0,-1,-2的情况
避免这种情况发生
保证if(tickets>0)
其他线程一定要保证一个线程中的System.println
一个程序中的只能允许一个线程可以执行的代码叫原子代码
只要将原子代码放在一个同步语句块中就可以,保证一个线程进入一个程序代码中
上面的程序中的原子代码是:
        if (tichests>0)
{   try{Tread.sleep(10);}catch(Excetption e){}_
         system.out.println("run:"+Thread.currentThread().getName()+"is saling ticket"+ tickets
--)
只要将它放在synchronized()
即:
class Threaddemo1
{
public static viod main(String [] args//main方法是在线程上进行的
    {
    TestThread tt= new TestThread ()

new Thread(tt).start();
new Thread(tt).start();
new Thread(tt).start();
new Thread(tt).start();//接受tt对象,然后创建多个线程
     }
}
class TestTread  implments Runnable//集成接口 runnable类灵活的多
{   int tickets = 100;
    String str= new String("")
   public void run()
    {
     while (true)
       {
synchronized(str);//任意类型的对象,
{
        if (tichests>0)
{   try{Tread.sleep(10);}catch(Excetption e){}_
         system.out.println("run:"+Thread.currentThread().getName()+"is saling ticket"+ tickets
--)//
}
}
       }
     }
}

synchronized(str);//任意类型的对象,线程的标志为是0还是1,开始,对象的标志位是1,已进入代码,标志位制成0,如果又有一个线程进入代码,发现标志位0,就会让出cpu给其他线程,这样就保证了,只能有一个线程进入这个代码。当第一个线程执行完代码后,会把标志位制成1,变为1以后,其他线程就会进入代码块。
标志位也就是锁起位,即监视器
同步,是以牺牲系统的性能为代价的。如果程序没有线程安全问题,尽量不要用多线程。
如果把  String str= new String("")放在run()方法中就会出现不安全现象,也会打印出0,-1,-2
因为每一个线程检查的监视器不是同一个,所以就会有问题
多个线程要同步,他们使用的对象一定是同一个监视器。
还可以用同步函数来实现多线程
class Threaddemo1
{
public static viod main(String [] args//main方法是在线程上进行的
    {
    TestThread tt= new TestThread ()

new Thread(tt).start();
new Thread(tt).start();
new Thread(tt).start();
new Thread(tt).start();//接受tt对象,然后创建多个线程
     }
}
class TestTread  implments Runnable
{   int tickets = 100;
    String str= new String("")
   public void run()
    {
          while (true)
         {
           sale();
         }
     }
   public void sale()
   {
         if (tichests>0)
      {   try{Tread.sleep(10);}catch(Excetption e){}_
         system.out.println("run:"+Thread.currentThread().getName()+"is saling ticket"+ tickets
--)//
       }
   }
}
这个线程不能实现同步的
如果在函数前加一个 sychronized 关键字
即   public sychronized  void sale()
就可以实现同步,如果一个方法前增加了关键字sychronized 只能有一个线程进入这个方法,其他的线程不允许进入这个方法。
sale方法使用的什么标志位?同步对象是this
代码块,函数来实现同步

线程启动的内部机制
start()不是cpu马上就执行这个线程。只是线程准备到就绪状态,如果cpu还在原来的线程上执行,将还在继续。
try{Thread.sleep(1);}catch(Exception e){}

方法中的监视器就是this
如果一个方法和代码块进行同步,可以在代码块中增加this这样就可以达到同步的作用
即synchronized(this)

死锁的问题:
一个线程进入x监视器,另一个线程进入Y监视器,y又等x,x又等待y


TAG: JAVA

 

评分:0

我来说两句

日历

« 2024-04-13  
 123456
78910111213
14151617181920
21222324252627
282930    

数据统计

  • 访问量: 15469
  • 日志数: 33
  • 图片数: 1
  • 建立时间: 2008-02-18
  • 更新时间: 2008-09-18

RSS订阅

Open Toolbar