java对象锁和类锁全面解析,java对象锁和类锁区别

  java对象锁和类锁全面解析,java对象锁和类锁区别

  写爬虫互联网协议(互联网协议)被封了怎么解决?立即使用

  8锁问题演示

  1.标准访问

  /*手机类可以发邮件和发短信*/班级电话{

  公共同步void sendEmail()引发异常{

  系统。出去。println("* * *发送邮件");

  }

  公共同步void sendSMS()引发异常{

  系统。出去。println( * * * sendSMS );

  } }公共类Lock8Demo {

  公共静态void main(String[] args)引发中断的异常{

  //创建一个资源类

  Phone Phone=new Phone();

  新线程(()-{

  尝试{

  电话。发送电子邮件();

  } catch(异常e) {

  //TODO自动生成的捕捉块

  e。printstacktrace();

  }

  },一)。start();

  线程。睡眠(100);

  新线程(()-{

  尝试{

  电话。sendsms();

  } catch(异常e) {

  //TODO自动生成的捕捉块

  e。printstacktrace();

  }

  }, B ).start();

  }}

  标准访问,先打印邮件还是短信。

  不一定谁先被打印。取决于中央处理器的执行情况。激活他们的是主要的线程,后面谁先被调度,不知道。

  为了保证效果,我们在A和B的代码之间加线程。睡眠(100)。此时,可以确保A先被打印。解释:

  只要一个资源类里面,不管它有多少个同步方法,只要一个线程先访问了资源类里面的任何一个同步方法,那么它锁的不是这一个方法,锁的是该方法所在的整个资源类。也就是说,锁的是对象。它锁的不是当前的方法。

  也就是说,这些同步的的方法都属于同一个资源类里面,锁的是整个资源类。

  2.在邮件方法中暂停4秒,请问先打印邮件还是短信

  /*手机类可以发邮件和发短信*/班级电话{

  公共同步void sendEmail()引发异常{

  时间单位10.25秒。睡眠(4);//表示暂停四秒,它是一个枚举类型

  系统。出去。println("* * *发送邮件");

  }

  公共同步void sendSMS()引发异常{

  系统。出去。println( * * * sendSMS );

  } }公共类Lock8Demo {

  公共静态void main(String[] args)引发中断的异常{

  //创建一个资源类

  Phone Phone=new Phone();

  新线程(()-{

  尝试{

  电话。发送电子邮件();

  } catch(异常e) {

  //TODO自动生成的捕捉块

  e。printstacktrace();

  }

  },一)。start();

  线程。睡眠(100);

  新线程(()-{

  尝试{

  电话。sendsms();

  } catch(异常e) {

  //TODO自动生成的捕捉块

  e。printstacktrace();

  }

  }, B ).start();

  }}先打印邮件。同步方法获取的电话对象锁,睡觉不会释放锁。到了时间会立即执行。所以先打印邮件方法

  解释:

  它与问题一类似。只要一个资源类里面,不管它有多少个同步方法,只要一个线程先访问了资源类里面的任何一个同步方法,那么它锁的不是这一个方法,锁的是该方法所在的整个资源类。也就是说,锁的是对象。它锁的不是当前的方法。

  举个例子:我和班长要用同一个手机打电话,我肯定要等班长打完电话才能接着打。班长用的过程中停网了一段时间,那我也只能等班长打完。

  3.新增普通sayHello方法,请问先打印邮件还是hello

  先打印你好

  /*手机类可以发邮件和发短信*/班级电话{

  公共同步void sendEmail()引发异常{

  时间单位10.25秒。睡眠(4);//表示暂停四秒,它是一个枚举类型

  系统。出去。println("* * *发送邮件");

  }

  公共同步void sendSMS()引发异常{

  系统。出去。println( * * * sendSMS );

  }

  public void sayHello(){

  系统。出去。println( * * *说你好);

  } }公共类Lock8Demo {

  公共静态void main(String[] args)引发中断的异常{

  //创建一个资源类

  Phone Phone=new Phone();

  新线程(()-{

  尝试{

  电话。发送电子邮件();

  } catch(异常e) {

  //TODO自动生成的捕捉块

  e。printstacktrace();

  }

  },一)。start();

  线程。睡眠(100);

  新线程(()-{

  尝试{

  //电话。发送短信();

  电话。问好();

  } catch(异常e) {

  //TODO自动生成的捕捉块

  e。printstacktrace();

  }

  }, B ).start();

  }}解释:加个普通方法后发现和同步锁无关。因此它无需等待同步锁释放。

  这里可以举一个例子。班长用它的手机要打电话。而我要向班长借手机充电线,这两个不互斥,因此可以在班长打电话完之前就借走充电线。

  4.两部手机,请问先打印邮件还是短信

  /*手机类可以发邮件和发短信*/班级电话{

  公共同步void sendEmail()引发异常{

  时间单位10.25秒。睡眠(4);//表示暂停四秒,它是一个枚举类型

  系统。出去。println("* * *发送邮件");

  }

  公共同步void sendSMS()引发异常{

  系统。出去。println( * * * sendSMS );

  }

  public void sayHello(){

  系统。出去。println( * * *说你好);

  } }公共类Lock8Demo {

  公共静态void main(String[] args)引发中断的异常{

  //创建一个资源类

  Phone Phone=new Phone();

  Phone 2=new Phone();

  新线程(()-{

  尝试{

  电话。发送电子邮件();

  } catch(异常e) {

  //TODO自动生成的捕捉块

  e。printstacktrace();

  }

  },一)。start();

  线程。睡眠(100);

  新线程(()-{

  尝试{

  //电话。发送短信();

  //电话。问好();

  电话2。sendsms();

  } catch(异常e) {

  //TODO自动生成的捕捉块

  e。printstacktrace();

  }

  }, B ).start();

  }}

  解释:这里可以举一个例子,班长用它的手机法邮件。我用我自己的手机打电话。那么谁先谁后就没有关系。

  5.两个静态同步方法,同一部手机,请问先打印邮件还是短信

  /*手机类可以发邮件和发短信*/班级电话{

  公共静态同步void sendEmail()引发异常{

  时间单位10.25秒。睡眠(4);//表示暂停四秒,它是一个枚举类型

  系统。出去。println("* * *发送邮件");

  }

  公共静态同步void sendSMS()引发异常{

  系统。出去。println( * * * sendSMS );

  }

  public void sayHello(){

  系统。出去。println( * * *说你好);

  } }公共类Lock8Demo {

  公共静态void main(String[] args)引发中断的异常{

  //创建一个资源类

  Phone Phone=new Phone();

  Phone 2=new Phone();

  新线程(()-{

  尝试{

  电话。发送电子邮件();

  } catch(异常e) {

  //TODO自动生成的捕捉块

  e。printstacktrace();

  }

  },一)。start();

  线程。睡眠(100);

  新线程(()-{

  尝试{

  电话。sendsms();

  //电话。问好();

  //手机2。sendsms();

  } catch(异常e) {

  //TODO自动生成的捕捉块

  e。printstacktrace();

  }

  }, B ).start();

  }}

  解释:可以与问题6一起分析

  6.两个静态同步方法,两部手机,请问先打印邮件还是短信

  /*手机类可以发邮件和发短信*/班级电话{

  公共静态同步void sendEmail()引发异常{

  时间单位10.25秒。睡眠(4);//表示暂停四秒,它是一个枚举类型

  系统。出去。println("* * *发送邮件");

  }

  公共静态同步void sendSMS()引发异常{

  系统。出去。println( * * * sendSMS );

  }

  public void sayHello(){

  系统。出去。println( * * *说你好);

  } }公共类Lock8Demo {

  公共静态void main(String[] args)引发中断的异常{

  //创建一个资源类

  Phone Phone=new Phone();

  Phone 2=new Phone();

  新线程(()-{

  尝试{

  电话。发送电子邮件();

  } catch(异常e) {

  //TODO自动生成的捕捉块

  e。printstacktrace();

  }

  },一)。start();

  线程。睡眠(100);

  新线程(()-{

  尝试{

  //电话。发送短信();

  //电话。问好();

  电话2。sendsms();

  } catch(异常e) {

  //TODO自动生成的捕捉块

  e。printstacktrace();

  }

  }, B ).start();

  }}

  解析:

  静电属于一个类。也就说,他不属于当前对象这的一个独立的个体。而是属于全局的班级。这就要考虑对象锁和全局锁的区别。全局锁即类锁。此时不管是一个电话还是多个电话都来自于同一个类电话类。现在不管你锁到了哪个对象,我都要等他释放完了这个锁才能使用。

  7.1个静态同步方法,1个普通同步方法,同一部手机,请问先打印邮件还是短信

  /*手机类可以发邮件和发短信*/班级电话{

  公共静态同步void sendEmail()引发异常{

  时间单位10.25秒。睡眠(4);//表示暂停四秒,它是一个枚举类型

  系统。出去。println("* * *发送邮件");

  }

  公共同步void sendSMS()引发异常{

  系统。出去。println( * * * sendSMS );

  }

  public void sayHello(){

  系统。出去。println( * * *说你好);

  } }公共类Lock8Demo {

  公共静态void main(String[] args)引发中断的异常{

  //创建一个资源类

  Phone Phone=new Phone();

  Phone 2=new Phone();

  新线程(()-{

  尝试{

  电话。发送电子邮件();

  } catch(异常e) {

  //TODO自动生成的捕捉块

  e。printstacktrace();

  }

  },一)。start();

  线程。睡眠(100);

  新线程(()-{

  尝试{

  电话。sendsms();

  //电话。问好();

  //手机2。sendsms();

  } catch(异常e) {

  //TODO自动生成的捕捉块

  e。printstacktrace();

  }

  }, B ).start();

  }}

  一个静态,一个普通。是同一个手机。静态方法锁定该类。相当于锁了一个校门,另一种是常见的同步方法,锁定当前对象。比如老师,普通孩子。锁的对象不同。不冲突。

  8.1个静态同步方法,1个普通同步方法,两部手机,请问先打印邮件还是短信

  /*手机可以发送电子邮件和短信*/class Phone{

  公共静态同步void sendEmail()引发异常{

  时间单位。seconds . sleep(4);//表示暂停4秒,是枚举类型。

  system . out . println(“* * * send email”);

  }

  公共同步void sendSMS()引发异常{

  system . out . println( * * * sendSMS );

  }

  public void sayHello(){

  system . out . println( * * * say hello );

  } }公共类Lock8Demo {

  公共静态void main(String[] args)引发InterruptedException {

  //创建资源类

  Phone Phone=new Phone();

  Phone 2=new Phone();

  新线程(()-{

  尝试{

  phone . send email();

  } catch(异常e) {

  //TODO自动生成的catch块

  e . printstacktrace();

  }

  },一)。start();

  thread . sleep(100);

  新线程(()-{

  尝试{

  //phone . send SMS();

  //phone . say hello();

  phone 2 . sendsms();

  } catch(异常e) {

  //TODO自动生成的catch块

  e . printstacktrace();

  }

  }, B )。start();

  }}

  说明:这个同上。

  8锁理论解释

  1.如果一个对象中有多个同步的方法,在某个时刻,只要一个线程调用其中一个同步的方法,其他线程就只能等待。换句话说,在某个时刻,只有一个线程可以访问这些同步的方法。

  锁定的是当前对象。被锁定后,其他线程不能进入当前对象的其他同步方法。

  加了一个常用方法后发现和同步锁没关系。

  转移两个对象后,就不是同一个锁了,情况马上就变了。

  使用静态同步方法后,情况立即改变。

  所有非静态同步方法都使用同一个锁,即实例对象本身。

  2.2.synchronized同步的基础:java中的每个对象都可以用作锁。

  它体现为以下三种形式:

  对于常见的同步方法,锁是当前实例对象。对于同步方法块,锁是在同步括号中配置的对象。

  例如,在方法中编写。

  同步(这){

  }对于静态同步方法,锁是当前类的类对象。当一个进程试图访问一个同步代码块时,它必须首先获得锁,当退出或抛出异常时,锁必须被释放。

  也就是说,实例对象的非静态同步方法获得锁后,实例对象的其他非静态同步方法必须等待获得锁的方法释放锁后才能获得锁。但是,其他实例对象的非静态同步方法可以获得它们自己的锁,而无需等待已经获得锁的非静态同步方法释放锁,因为它们使用与该实例对象的非静态同步方法不同的锁。

  所有静态同步方法都使用同一个锁——类对象本身。这两把锁是两个不同的对象,所以静态同步方法与非静态同步方法之间是不会有竞态条件的。(第78题)。也就是一个锁类,一个锁本,两者不冲突。但是一旦一个静态同步方法获取锁后,其他的静态同步方法都必须等待该方法释放锁后才能获取锁。而不管是同一个实例对象的静态方法之间,还是不同的实例对象的静态同步方法之间,只要它们同一个类的实例对象。(问题56)以上是Java对八锁的介绍,会让你对对象锁和类锁的细节有一个透彻的了解。请多关注我们的其他相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: