线程中的同步(synchronized)的解释和例子

package synh;

/*class ThreadDemo implements Runnable{
 int tickets = 100;//票数
 String str = new String("");
 public void run(){
  while(true){
   /*
    *分析synchronized方法
    *synchronized代码块中的语句只能有一个线程在执行
    *
    *任意一个对象都有一个标志位,有1和0两种状态
    *当程序执行到synchronized代码块的时候线程会检查对象的标志位是1还是0
    *如果是1则执行程序,同是将对象的标志位设置为0,其他线程执行到synchronized代码块时一看对象标志位为0
    *则线程会阻塞,一直等到对象的标志位为1再执行下面的程序
    *本程序中一共产生了4个线程,当一个线程执行synchronized代码块的时候其他三个线程会发生阻塞
    *第一个线程执行完synchronized代码块后会把对象的标志位设置为1,其他的三个线程中的其中一个
    *会抢到synchronized代码块的执行权,同时会把对象的标志位设置为0,就以这样的顺序循环执行
    *
    *我们也可以把对象标志位看成一个监视器,当一个线程执行到synchronized代码块的时候会检查监视器的
    *状态,一个刚执行完synchronized代码块的线程也可以再次检查监视器并执行synchronized代码块
    *
    *多个线程要实现同步,必须使用相同的监视器对象(本例中4个线程都是用的str同一个对象),
    *如果多个线程使用的不是同一个监视器对象则达不到同步的效果
   *
   synchronized(str){
    if(tickets > 0){
     try{Thread.sleep(1);}catch(Exception e){}
     System.out.println(Thread.currentThread().getName() + " is salling ticket --- " + tickets--);
    }
   }
  }
 }
}*/

class ThreadDemo implements Runnable{
 int tickets = 100;//票数
 String str = new String("");
 //在一个方法里实现同步
 public void run(){
  while(true){
   sale();
  }
 }
 /*
  *同步方法和同步块道理一样,这里就不再说了
  *当一个线程执行同步方法的时候其他的方法也不能再执行同步方法中的语句
  */
 public synchronized void sale(){
  if(tickets > 0){
     try{Thread.sleep(1);}catch(Exception e){}//模拟不同步的实现
     System.out.println(Thread.currentThread().getName() + " is salling ticket --- " + tickets--);
    }
 }
}

class ThreadTest{
 public static void main(String [] args){
  ThreadDemo td = new ThreadDemo();
  /*
   *生成4个线程
   *
   */
  new Thread(td).start();
  new Thread(td).start();
  new Thread(td).start();
  new Thread(td).start();
 }

看完了线程间的同步,再看看同步方法和同步代码块之间的同步

package synch;

class ThreadDemo implements Runnable{
 int tickets = 100;//票数
 String str = new String("");
 //在一个方法里实现同步
 public void run(){
  if(str.equals("method")){
   while(true){
    sale();
   }
  }
  else{
   while(true){
    synchronized(this){
     if(tickets > 0){
      try{Thread.sleep(1);}catch(Exception e){}
      System.out.println(Thread.currentThread().getName() + " is salling ticket --- " + tickets--);
     }
    }
   }
  }
 }
 /*
  *同步方法和同步块道理一样,这里就不再说了
  *当一个线程执行同步方法的时候其他的方法也不能再执行同步方法中的语句
  */
 public synchronized void sale(){
  if(tickets > 0){
     try{Thread.sleep(1);}catch(Exception e){}//模拟不同步的实现
     System.out.println("method: " + Thread.currentThread().getName() + " is salling ticket --- " + tickets--);
    }
 }
}

class ThreadTest1{
 public static void main(String [] args){
  ThreadDemo td = new ThreadDemo();
  /*
   *生成4个线程
   *
   */
  new Thread(td).start();
  //这里写这个sleep()是为了让CPU转到当前线程来执行
  try{Thread.sleep(1);}catch(Exception e){}  td.str = "method";
  new Thread(td).start();
  //new Thread(td).start();
  //new Thread(td).start();
 }
}

这里最关键的一点就是要想让同步方法和同步代码块同步,两者就要使用相同的监视器对象

本程序中用的同一个监视器对象是this

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值