java 线程的监视器与互斥概念、以及监视器作用的几个范围

线程的监视器,即线程所持有的锁,也就是synchronized所关联的对象。

线程的互斥,即同一数据的访问,为了访问数据的同步,维护数据的原子性。

线程的互斥 由线程的监视器机制来实现。

下面举例几种监视器:

  1.作用域成员变量:

 

 class ViewData {
    private Object lock=new Object();
    public void viewData(String data){
      Synchronized(lock)
      {
       for(int i=0;i<10;i++){
         system.out.println(data);
       }
      }
    }
   }
   public MyThread extends Thread{
  private ViewData vd;
  public MyThread(ViewData vd)
  {
    this.vd=vd;
  }
  public void run(){
      while(true){
      try{
         Thread.sleep(10);
      }catch(Exception e){
        e.printStatcke();
     }
    //执行
    vd.viewData("zhangsanzhangsan");
    }
    }
  }
 
//main函数--执行
public static void main(String[] args) {
  ViewData vd=new ViewData();
  MyThread mtd1=new MyThread(vd);
  MyThread mtd2=new MyThread(vd);
  mtd1.start();
  mtd2.start();
  //可以尝试 将ViewData中的Synchronized关键字去掉  看一下数据的脏读
}

  ==============================================================

  2作用域方法块

    将ViewData中的viewData方法改成如下:

    

    

public void viewData(String data){
      Synchronized(this)
      {
       for(int i=0;i<10;i++){
         system.out.println(data);
       }
      }
    }或者
    
    public synchronized void viewData(String data){
       for(int i=0;i<10;i++){
         system.out.println(data);
       }
    }

 

一样可以实现同步:

  3.作用域整个类:

   如果类中的方法是静态方法  那么对于该类中的非静态方法所使用的锁时  既不能对代码块同步 也不能够对实例的成员变量同步,要同步的是class对象,任何加载与jvm中的类class是一个类的唯一class对象,所以如下方法是:

  public static synchronized void viewDataOne(String data){

    for(int i=0;i<10;i++){

      System.out.println(data);

    }

  }

此处synchronized所关联的对象是ViewData.class,所以对于实例的非静态方法而言,对共享数据的访问需要使用synchronized(ViewData.class)来同步代码块。

你可能感兴趣的:(java 线程的监视器与互斥概念、以及监视器作用的几个范围)