多线程间的资源共享
关键词
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(); } } } }
参考资料