java

位置:IT落伍者 >> java >> 浏览文章

Java:使用synchronized和Lock对象获取对象锁


发布日期:2022年09月09日
 
Java:使用synchronized和Lock对象获取对象锁

在并发环境下解决共享资源沖突问题时可以考虑使用锁机制

对象的锁

所有对象都自动含有单一的锁

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()

               

上一篇:Java split方法拆分使用竖线为分隔符的字符串

下一篇:分享:让Java程序带着jre一起上路