`

Java lock & condition

    博客分类:
  • J2SE
阅读更多

 

java Lock & Condition, provide a similar, yet more extensive locking mechanism than synchronized,

 

Lock:

similar to the monitor lock used by synchronized, but more powerfull,

 

Condition:

bound to lock, provide methods similar to wait()/notify()/notifyAll() of Object,

 

------

class & interface

 

* Lock

interface of lock,

* ReentrantLock

basic implementation of Lock

* Condition

interface of condition,

* ReadWriteLock

interface, read/write version of Lock,

* ReentrantReadWriteLock

basic implementation of ReadWriteLock,


------

code

 

    lock test:

 

package eric.j2se.concurrence.lockcondition;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Lock test
 * 
 * @author eric
 * @date Aug 14, 2012 8:04:57 PM
 */
public class LockTest {
	private static int i;
	private static Lock lk = new ReentrantLock();

	public static void test() {
		List<Thread> list = new ArrayList<Thread>();
		int tcount = 3;
		// prepare threads
		for (int i = 0; i < tcount; i++) {
			list.add(new Thread(new TmpRunnable(), "t-" + i));
		}
		// start threads
		for (int i = 0; i < tcount; i++) {
			list.get(i).start();
		}
	}

	private static class TmpRunnable implements Runnable {
		@Override
		public void run() {
			lk.lock();
			try {
				printTime("begin");
				Thread.sleep(1000 * 1); // sleep a while, for test purpose
				printTime("end");
			} catch (InterruptedException e) {
				e.printStackTrace();
			} finally {
				lk.unlock();
			}
		}
	}

	public static void printTime() {
		printTime("");
	}

	/**
	 * print thread name & time
	 * 
	 * @param info
	 *            additional info to print
	 */
	public synchronized static void printTime(String info) {
		System.out.printf("%s:\t%d,\t,%d,\t%s\n", Thread.currentThread().getName(), ++i, System.currentTimeMillis() / 1000, info);
	}

	public static void main(String[] args) {
		test();
	}
}

 

 

    condition test:

package eric.j2se.concurrence.lockcondition;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Condition test
 * 
 * @author eric
 * @date Aug 14, 2012 9:10:44 PM
 */
public class ConditionTest {
	private static int i;
	private static int bufSize = 26, size;
	private static char cStart = 97;
	private static char[] cbuf = new char[bufSize];

	private static Lock lk = new ReentrantLock();
	private static Condition cdEmpty = lk.newCondition();
	private static Condition cdFull = lk.newCondition();

	private static final int testInterval = 500; // interval of each step in milliseconds, for test

	/**
	 * fill buffer, start when buffer is empty
	 * 
	 * @throws InterruptedException
	 */
	public static void fill() throws InterruptedException {
		lk.lock();
		try {
			while (size == bufSize) { // buffer is full, wait for condition empty
				cdEmpty.await();
			}

			System.out.printf("\n\n------\nstart fill\n\n");
			while (size < bufSize) { // buffer is not full now, fill it
				char c = (char) (cStart + size);
				cbuf[size++] = c;
				printTime("put: " + new Character(c));
				Thread.sleep(testInterval);
			}
			cdFull.signal(); // buffer is full filled now, need to be read
			System.out.printf("\nbuffer full\n------\n\n");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lk.unlock();
		}
	}

	/**
	 * take from buffer & empty it, start when buffer is full
	 * 
	 * @throws InterruptedException
	 */
	public static void take() throws InterruptedException {
		lk.lock();
		try {
			while (size != bufSize) { // not full, wait for condition full
				cdFull.await();
			}
			System.out.printf("\n\n------\nstart take\n\n");
			for (int i = 0; i < bufSize; i++) { // now is full, take
				printTime("take: " + new Character(cbuf[i]));
				size--;
				Thread.sleep(testInterval);
			}
			cdEmpty.signal(); // buffer is empty now, need to be fill
			System.out.printf("\nbuffer empty\n------\n\n");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lk.unlock();
		}
	}

	public static void test() {
		// thread to fill buffer
		Thread tFill = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					while (true)
						fill();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}, "t-fill");

		// thread to take from buffer
		Thread tTake = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					while (true)
						take();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}, "t-take");
		tTake.start();
		tFill.start();
	}

	public static void printTime() {
		printTime("");
	}

	/**
	 * print thread name & time
	 * 
	 * @param info
	 *            additional info to print
	 */
	public synchronized static void printTime(String info) {
		System.out.printf("%s:\t%d,\t,%d,\t%s\n", Thread.currentThread().getName(), ++i, System.currentTimeMillis() / 1000, info);
	}

	public static void main(String[] args) {
		test();
	}
}
 

 

    read/write lock test:

package eric.j2se.concurrence.lockcondition;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * Read Write Lock test
 * 
 * @author eric
 * @date Aug 14, 2012 10:34:08 PM
 */
public class ReadWriteLockTest {
	private static int i;

	private static ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
	private static Lock rlk = lock.readLock();
	private static Lock wlk = lock.writeLock();

	private static String data = "";

	private static volatile long lastUpdate; // track last publish date

	/**
	 * publish data, use write lock,
	 * 
	 * @param newData
	 */
	public static void publish(String newData) {
		wlk.lock();
		try {
			printTime("begin publish");
			data = newData;
			lastUpdate = System.currentTimeMillis(); // modify last update date
			printTime("data:\n\t" + data);
			printTime("end publish");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			wlk.unlock();
		}
	}

	/**
	 * view data, use read lock
	 * 
	 * @param previousView
	 *            last viewed publish date
	 * @return date of new publish, or -1 if no new publish
	 */
	public static long view(long previousView) {
		if (previousView < lastUpdate) { // new publish
			rlk.lock();
			try {
				printTime("view data:\n\t" + data);
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				rlk.unlock();
			}
			return lastUpdate;
		} else { // no new publish
			printTime("no new publish yet");
			return -1;
		}
	}

	public static void test() throws InterruptedException {
		Thread tPublish = new Thread(new Runnable() {
			@Override
			public void run() {
				while (true) {
					publish("hi, xxxxxx, data_" + i + "_xxxxxx");
					try {
						Thread.sleep(1000 * 10); // update interval
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}, "t-publish");

		// prepare view threads
		int tViewCount = 3; // count of view thread
		List<Thread> tViewList = new ArrayList<Thread>();
		final List<Long> tLastView = new ArrayList<Long>(); // keep track of last viewed publish date
		for (int i = 0; i < tViewCount; i++) {
			final int _index = i;
			tViewList.add(new Thread(new Runnable() {
				@Override
				public void run() {
					while (true) {
						long _lastDate = view(tLastView.get(_index));
						if (_lastDate > 0) {
							tLastView.set(_index, _lastDate); // update last viewed publish date, if has new publish
						}
						try {
							Thread.sleep(1000 * 4); // view interval
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
			}, "t-view-" + i));
			tLastView.add(0L);
		}

		tPublish.start();
		for (int i = 0; i < tViewCount; i++) {
			tViewList.get(i).start();
			Thread.sleep(1000 * 5); // start interval of view threads
		}
	}

	public static void printTime() {
		printTime("");
	}

	/**
	 * print thread name & time
	 * 
	 * @param info
	 *            additional info to print
	 */
	public synchronized static void printTime(String info) {
		System.out.printf("%s:\t%d,\t,%d,\t%s\n", Thread.currentThread().getName(), ++i, System.currentTimeMillis() / 1000, info);
	}

	public static void main(String[] args) throws InterruptedException {
		test();
	}
}
 


------


 

分享到:
评论

相关推荐

    JavaLock与Condition的理解Reentran

    JavaLock与Condition的理解ReentrantLock锁的简单使用技巧共5页.pdf.zip

    生产者-消费者(lock和condition).zip

    通过java语言编写的生产者消费者,实现方法为lock类和condition类的配合完成。

    java中的Lock类和Condition类.docx

    在jdk1.5以后,JAVA提供了Lock类来实现和synchronized一样的功能,并且还提供了Condition来显示线程间通信。 Lock类是Java类来提供的功能,丰富的api使得Lock类的同步功能比synchronized的同步更强大。本文章的所有...

    Java多线程中ReentrantLock与Condition详解

    主要介绍了Java多线程中ReentrantLock与Condition详解,需要的朋友可以参考下

    java 锁 Lock接口详解.docx

    Condition 接口描述了可能会与锁有关联的条件变量。这些变量在用法上与使用 ...需要特别指出的是,单个 Lock 可能与多个 Condition 对象关联。为了避免兼容性问题,Condition 方法的名称与对应的 Object 版本中的不同。

    Java学习源码Java多线程的代码

    在char04包里放置了Java中Lock类的知识的代码,内容如下: Lock类 Lock类其他功能 Condition类 Condition类其他功能 读写锁 在char05包里放置了生产者/消费者的知识的代码,内容如下: 一对一 生产者/消费...

    56.Lock-ReentranLock-使用多个Condition实现通知部分线程.mp4

    在学习Java过程中,自己收集了很多的Java的学习资料,分享给大家,有需要的欢迎下载,希望对大家有用,一起学习,一起进步。

    Java中的Runnable接口最全讲义

    6.4 使用Lock和Condition 6.5 使用volatile关键字 7. 线程通信: 7.1 使用wait()和notify()方法 7.2 使用Lock和Condition 8. 线程池: 8.1 线程池的概述 8.2 使用Executor框架创建线程池 8.3 线程池的优势和适用场景...

    基础技术部牛路《Java多线程入阶分享》纯干货

    4.线程间通信:lock、condition、wait、notify、notifyAll 5.Lock-free:atomic、concurrentMap.putIfAbsent、CopyOnWriteArrayList 6.关于锁的经验介绍 7.并发流程控制手段:CountDownLatch、Barrier 8.定时器:...

    Lock锁的底层原理完整版

    此外,Lock接口还有一个带条件的锁——Condition接口的实现类ReentrantLock。这种带条件的锁使得线程可以在一定条件下挂起等待,直到其它线程唤醒它。 在实际使用场景中,例如多个用户同时操作一个银行账户的情况,...

    java 并发编程 多线程

    java 并发 编程 多线程 concurrent lock condition executorserice executor java.util.curcurrent.

    阿里Java并发程序设计教程

    4、线程间的协调手段:lock、condition、wait、notify、notifyAll ☆ ☆ ☆ 5、Lock-free: atomic、concurrentMap.putIfAbsent、CopyOnWriteArrayList ☆ ☆ ☆ 6、关于锁使用的经验介绍 7、并发流程控制手段:...

    Java并发程序设计教程

    4、线程间的协调手段:lock、condition、wait、notify、notifyAll☆☆☆ 5、Lock-free: atomic、concurrentMap.putIfAbsent、CopyOnWriteArrayList☆☆☆ 6、关于锁使用的经验介绍 7、并发流程控制手段:...

    Java编程并发程序设计

    4、线程间的协调手段:lock、condition、wait、notify、notifyAll☆☆☆ 5、Lock-free: atomic、concurrentMap.putIfAbsent、CopyOnWriteArrayList☆☆☆ 6、关于锁使用的经验介绍 7、并发流程控制手段:...

    Java JDK 7学习笔记(国内第一本Java 7,前期版本累计销量5万册)

    11.2.1 lock、readwritelock与condition 349 11.2.2 使用executor 357 11.2.3 并行collection简介 370 11.3 重点复习 373 11.4 课后练习 375 chapter12 通用api 377 12.1 日志 378 12.1.1 日志api简介...

    Java 7并发编程实战手册

    2.8 在锁中使用多条件(Multiple Condition) 69 第3章 线程同步辅助类 77 3.1 简介 77 3.2 资源的并发访问控制 78 3.3 资源的多副本的并发访问控制 83 3.4 等待多个并发事件的完成 87 3.5 在集合...

    JAVA高质量并发详解,多线程并发深入讲解

    接着,深入讲解了Java并发编程的核心API,如synchronized关键字、Lock接口、Condition接口、Semaphore等,帮助读者掌握Java并发编程的基本工具和方法。 除了基础知识和API的讲解,本书还重点介绍了Java并发编程的...

    java多线程实现生产者和消费者

    java多线程实现生产者和消费者 ,4种实现方式,分别为synchronizated,condition和lock,信号量,阻塞队列

Global site tag (gtag.js) - Google Analytics