熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

Java:使用synchronized和Lock對象獲取對象鎖

2022-06-13   來源: Java核心技術 

  在並發環境下解決共享資源沖突問題時可以考慮使用鎖機制

  對象的鎖

  所有對象都自動含有單一的鎖

  JVM負責跟蹤對象被加鎖的次數如果一個對象被解鎖其計數變為在任務(線程)第一次給對象加鎖的時候計數變為每當這個相同的任務(線程)在此對象上獲得鎖時計數會遞增

  只有首先獲得鎖的任務(線程)才能繼續獲取該對象上的多個鎖

  每當任務離開一個synchronized方法計數遞減當計數為的時候鎖被完全釋放此時別的任務就可以使用此資源

  synchronized同步塊

  同步到單一對象鎖

  當使用同步塊時如果方法下的同步塊都同步到一個對象上的鎖則所有的任務(線程)只能互斥的進入這些同步塊

  Resourcejava演示了三個線程(包括main線程)試圖進入某個類的三個不同的方法的同步塊中雖然這些同步塊處在不同的方法中但由於是同步到同一個對象(當前對象 synchronized (this))所以對它們的方法依然是互斥的

  Resourcejava

  package comzjlock;

  import ncurrentTimeUnit;

  public class Resource {

  public void f() {

  // other operations should not be locked

  Systemoutprintln(ThreadcurrentThread()getName()

  + :not synchronized in f());

  synchronized (this) {

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

  Systemoutprintln(ThreadcurrentThread()getName()

  + :synchronized in f());

  try {

  TimeUnitSECONDSsleep();

  } catch (InterruptedException e) {

  eprintStackTrace();

  }

  }

  }

  }

  public void g() {

  // other operations should not be locked

  Systemoutprintln(ThreadcurrentThread()getName()

  + :not synchronized in g());

  synchronized (this) {

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

  Systemoutprintln(ThreadcurrentThread()getName()

  + :synchronized in g());

  try {

  TimeUnitSECONDSsleep();

  } catch (InterruptedException e) {

  eprintStackTrace();

  }

  }

  }

  }

  public void h() {

  // other operations should not be locked

  Systemoutprintln(ThreadcurrentThread()getName()

  + :not synchronized in h());

  synchronized (this) {

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

  Systemoutprintln(ThreadcurrentThread()getName()

  + :synchronized in h());

  try {

  TimeUnitSECONDSsleep();

  } catch (InterruptedException e) {

  eprintStackTrace();

  }

  }

  }

  }

  public static void main(String[] args) {

  final Resource rs = new Resource();

  new Thread() {

  public void run() {

  rsf();

  }

  }start();

  new Thread() {

  public void run() {

  rsg();

  }

  }start();

  rsh();

  }

  }

  結果

  Thread:not synchronized in f()

  Thread:synchronized in f()

  main:not synchronized in h()

  Thread:not synchronized in g()

  Thread:synchronized in f()

  Thread:synchronized in f()

  Thread:synchronized in f()

  Thread:synchronized in f()

  Thread:synchronized in g()

  Thread:synchronized in g()

  Thread:synchronized in g()

  Thread:synchronized in g()

  Thread:synchronized in g()

  main:synchronized in h()

  main:synchronized in h()

  main:synchronized in h()

  main:synchronized in h()

  main:synchronized in h()

   同步到多個對象鎖

  Resourcejava演示了三個線程(包括main線程)試圖進入某個類的三個不同的方法的同步塊中這些同步塊處在不同的方法中並且是同步到三個不同的對象(synchronized (this)synchronized (syncObject)synchronized (syncObject))所以對它們的方法中的臨界資源訪問是獨立的

  Resourcejava

  package comzjlock;

  import ncurrentTimeUnit;

  public class Resource {

  private Object syncObject = new Object();

  private Object syncObject = new Object();

  public void f() {

  // other operations should not be locked

  Systemoutprintln(ThreadcurrentThread()getName()

  + :not synchronized in f());

  synchronized (this) {

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

  Systemoutprintln(ThreadcurrentThread()getName()

  + :synchronized in f());

  try {

  TimeUnitSECONDSsleep();

  } catch (InterruptedException e) {

  eprintStackTrace();

  }

  }

  }

  }

  public void g() {

  // other operations should not be locked

  Systemoutprintln(ThreadcurrentThread()getName()

  + :not synchronized in g());

  synchronized (syncObject) {

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

  Systemoutprintln(ThreadcurrentThread()getName()

  + :synchronized in g());

  try {

  TimeUnitSECONDSsleep();

  } catch (InterruptedException e) {

  eprintStackTrace();

  }

  }

  }

  }

  public void h() {

  // other operations should not be locked

  Systemoutprintln(ThreadcurrentThread()getName()

  + :not synchronized in h());

  synchronized (syncObject) {

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

  Systemoutprintln(ThreadcurrentThread()getName()

  + :synchronized in h());

  try {

  TimeUnitSECONDSsleep();

  } catch (InterruptedException e) {

  eprintStackTrace();

  }

  }

  }

  }

  public static void main(String[] args) {

  final Resource rs = new Resource();

  new Thread() {

  public void run() {

  rsf();

  }

  }start();

  new Thread() {

  public void run() {

  rsg();

  }

  }start();

  rsh();

  }

  }

  結果

  Thread:not synchronized in f()

  Thread:synchronized in f()

  main:not synchronized in h()

  main:synchronized in h()

  Thread:not synchronized in g()

  Thread:synchronized in g()

  Thread:synchronized in f()

  main:synchronized in h()

  Thread:synchronized in g()

  Thread:synchronized in f()

  main:synchronized in h()

  Thread:synchronized in g()

  Thread:synchronized in f()

  main:synchronized in h()

  Thread:synchronized in g()

  Thread:synchronized in f()

  main:synchronized in h()

  Thread:synchronized in g()

  Lock對象鎖

  除了使用synchronized外還可以使用Lock對象來創建臨界區Resourcejava的演示效果同ResourcejavaResourcejava的演示效果同Resourcejava

  Resourcejava

  package comzjlock;

  import ncurrentTimeUnit;

  import ncurrentlocksLock;

  import ncurrentlocksReentrantLock;

  public class Resource {

  private Lock lock = new ReentrantLock();

  public void f() {

  // other operations should not be locked

  Systemoutprintln(ThreadcurrentThread()getName()

  + :not synchronized in f());

  locklock();

  try {

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

  Systemoutprintln(ThreadcurrentThread()getName()

  + :synchronized in f());

  try {

  TimeUnitSECONDSsleep();

  } catch (InterruptedException e) {

  eprintStackTrace();

  }

  }

  } finally {

  lockunlock();

  }

  }

  public void g() {

  // other operations should not be locked

  Systemoutprintln(ThreadcurrentThread()getName()

  + :not synchronized in g());

  locklock();

  try {

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

  Systemoutprintln(ThreadcurrentThread()getName()

  + :synchronized in g());

  try {

  TimeUnitSECONDSsleep();

  } catch (InterruptedException e) {

  eprintStackTrace();

  }

  }

  } finally {

  lockunlock();

  }

  }

  public void h() {

  // other operations should not be locked

  Systemoutprintln(ThreadcurrentThread()getName()

  + :not synchronized in h());

  locklock();

  try {

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

  Systemoutprintln(ThreadcurrentThread()getName()

  + :synchronized in h());

  try {

  TimeUnitSECONDSsleep();

  } catch (InterruptedException e) {

  eprintStackTrace();

  }

  }

  } finally {

  lockunlock();

  }

  }

  public static void main(String[] args) {

  final Resource rs = new Resource();

  new Thread() {

  public void run() {

  rsf();

  }

  }start();

  new Thread() {

  public void run() {

  rsg();

  }

  }start();

  rsh();

  }

  }

  結果

  Thread:not synchronized in f()

  Thread:synchronized in f()

  main:not synchronized in h()

  Thread:not synchronized in g()

  Thread:synchronized in f()

  Thread:synchronized in f()

  Thread:synchronized in f()

  Thread:synchronized in f()

  main:synchronized in h()

  main:synchronized in h()

  main:synchronized in h()

  main:synchronized in h()

  main:synchronized in h()

  Thread:synchronized in g()

  Thread:synchronized in g()

  Thread:synchronized in g()

  Thread:synchronized in g()

  Thread:synchronized in g()

  Resourcejava

  package comzjlock;

  import ncurrentTimeUnit;

  import ncurrentlocksLock;

  import ncurrentlocksReentrantLock;

  public class Resource {

  private Lock lock = new ReentrantLock();

  private Lock lock = new ReentrantLock();

  private Lock lock = new ReentrantLock();

  public void f() {

  // other operations should not be locked

  Systemoutprintln(ThreadcurrentThread()getName()

  + :not synchronized in f());

  locklock();

  try {

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

  Systemoutprintln(ThreadcurrentThread()getName()

  + :synchronized in f());

  try {

  TimeUnitSECONDSsleep();

  } catch (InterruptedException e) {

  eprintStackTrace();

  }

  }

  } finally {

  lockunlock();

  }

  }

  public void g() {

  // other operations should not be locked

  Systemoutprintln(ThreadcurrentThread()getName()

  + :not synchronized in g());

  locklock();

  try {

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

  Systemoutprintln(ThreadcurrentThread()getName()

  + :synchronized in g());

  try {

  TimeUnitSECONDSsleep();

  } catch (InterruptedException e) {

  eprintStackTrace();

  }

  }

  } finally {

  lockunlock();

  }

  }

  public void h() {

  // other operations should not be locked

  Systemoutprintln(ThreadcurrentThread()getName()

  + :not synchronized in h());

  locklock();

  try {

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

  Systemoutprintln(ThreadcurrentThread()getName()

  + :synchronized in h());

  try {

  TimeUnitSECONDSsleep();

  } catch (InterruptedException e) {

  eprintStackTrace();

  }

  }

  } finally {

  lockunlock();

  }

  }

  public static void main(String[] args) {

  final Resource rs = new Resource();

  new Thread() {

  public void run() {

  rsf();

  }

  }start();

  new Thread() {

  public void run() {

  rsg();

  }

  }start();

  rsh();

  }

  }

  結果

  Thread:not synchronized in f()

  Thread:synchronized in f()

  main:not synchronized in h()

  main:synchronized in h()

  Thread:not synchronized in g()

  Thread:synchronized in g()

  Thread:synchronized in f()

  main:synchronized in h()

  Thread:synchronized in g()

  Thread:synchronized in f()

  main:synchronized in h()

  Thread:synchronized in g()

  Thread:synchronized in f()

  main:synchronized in h()

  Thread:synchronized in g()

  Thread:synchronized in f()

  main:synchronized in h()

  Thread:synchronized in g()


From:http://tw.wingwit.com/Article/program/Java/hx/201311/26181.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.