多线程间的资源共享
关键词
synchronized、sychronized块、并发、automic、Mutex Lock、volatile、锁的作用域、Java对象实例上的锁、static method上的synchronized
锁的语法
在类对象实例声明的锁,依据修饰符static可区分单实例拥有的锁和多实例共享的锁,通过使用synchronized标记类的某个方法支持同步,它有几种不同的写法可在一些具体场景时可选择最适合的写法,但不能盲目去缩小synchronized的作用域而增加代码结构的复杂度。
每个class对象实例只有一个thread可以执行syncornized method。
每个class只有一个thread可以执行synchronized static method。
public class Resource {
private Object lockInst = new Object();
public void doWork() {
synchronized(lockInst) {
//do something
}
}
public synchronized void doWorkSync() {
//do something
}
public void doWorkSync2() {
synchronized(this) {
//do something
}
}
}
public class Resource {
private static Object lockInst = new Object();
public void doWork() {
synchronized(lockInst) {
//do something
}
}
}
类static方法上的synchronized
public class Resource {
private static Object lockInst = new Object();
public static void doWork() {
synchronized(lockInst) {
//do something
}
}
public synchronized static void doWorkSync() {
//do something
}
public static void doWorkSync2() {
synchronized(Resource.class) {
//do something
}
}
}
练习
package org.ybygjy.thread3th.syn;
/**
* 多线程同步的锁
* <p>
* 1、创建多线程共享的资源对象,这个对象提供synchronized行为
* <p>
* 2、创建多个线程对象,并且都持有公共的共享资源
* @author WangYanCheng
* @version 2012-9-1
*/
public class SynchronizedLockTest {
/**
* 对象实例级别的锁
*/
public static void doTest1() {
InstanceLock tmInst = new InstanceLock();
for (int i = 0; i < 3; i++) {
new TestThread(tmInst).start();
}
}
/**
* 类级别的锁
*/
public static void doTest2() {
for (int i = 0; i < 3; i++) {
new TestThread(true).start();
}
}
/**
* 混合使用
*/
public static void doTest3() {
InstanceLock tmInst = new InstanceLock();
for (int i = 0; i < 3; i++) {
new TestThread(tmInst, true).start();
}
}
/**
* 测试入口
* @param args 参数列表
*/
public static void main(String[] args) {
//SynchronizedLockTest.doTest1();
//SynchronizedLockTest.doTest2();
SynchronizedLockTest.doTest3();
while ((Thread.activeCount()) != -1) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* 线程共享操作的资源对象_带有对象实例级别的锁
* @author WangYanCheng
* @version 2012-9-2
*/
class InstanceLock {
/** 对象实例级别共享 */
private Object objKey = new Object();
/** 实例变量 */
private int counter;
@Override
public String toString() {
return objKey.toString();
}
/**
* 某一行为
*/
public void doWork() {
synchronized (objKey) {
System.out.println(Thread.currentThread().getName() + "__" + (counter++));
if ("Thread-0".equals(Thread.currentThread().getName())) {
try {
Thread.currentThread().interrupt();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
/**
* 线程共享操作的资源对象_带有对象实例级别的锁
* @author WangYanCheng
* @version 2012-9-2
*/
class ClassicLock {
/** 类级别的锁 */
private static Object objKey = new Object();
/** 类变量 */
private static int counter;
/**
* 行为
*/
public static void doWork() {
synchronized (objKey) {
System.out.println(Thread.currentThread().getName() + "__" + (counter++));
if ("Thread-0".equals(Thread.currentThread().getName())) {
try {
Thread.currentThread().interrupt();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
/**
* 定义测试用线程类
* @author WangYanCheng
* @version 2012-9-2
*/
class TestThread extends Thread {
/** 多线程实例共享资源 */
private InstanceLock tmInst;
/** 是否类级别共享资源 */
private final boolean isClassic;
/**
* Constructor
* @param isClassic true/false
*/
public TestThread(boolean isClassic) {
this.isClassic = isClassic;
}
/**
* Constructor
* @param tmInst {@link TestThread}
*/
public TestThread(InstanceLock tmInst) {
this.tmInst = tmInst;
this.isClassic = false;
}
/**
* Constructor
* @param tmInst {@link TestThread}
* @param isClassic true/false
*/
public TestThread(InstanceLock tmInst, boolean isClassic) {
this(isClassic);
this.tmInst = tmInst;
}
@Override
public void run() {
while (!isInterrupted()) {
if (!this.isClassic) {
tmInst.doWork();
} else if (null == tmInst) {
ClassicLock.doWork();
} else {
ClassicLock.doWork();
tmInst.doWork();
}
try {
sleep(1000);
} catch (InterruptedException e) {
this.interrupt();
}
}
}
}
参考资料
- Java Thread 3th