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)