`

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

    Java Lock与Condition是Java并发编程中的重要概念,它们提供了比synchronized关键字更细粒度的控制,从而使得多线程程序的设计和管理更加灵活高效。本文将深入探讨ReentrantLock(可重入锁)和Condition的基本原理、...

    java中的Lock类和Condition类.docx

    Java中的Lock类与Condition类是Java并发编程的重要组成部分,它们为多线程环境下的同步提供了更为灵活和强大的控制。在JDK 1.5及之后的版本中,Lock类作为替代synchronized关键字的一种方式出现,提供了更精细的锁...

    Java concurrency之Condition条件_动力节点Java学院整理

    在Java并发编程中,`Condition`接口是Java并发包(java.util.concurrent)中的一个重要组成部分,它提供了比`synchronized`关键字更为精细的线程同步和唤醒机制。`Condition`允许我们创建多个独立的等待队列,每个...

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

    在这个场景中,"生产者-消费者(lock和condition).zip"的文件内容可能包含一个使用Java语言实现的示例,它利用了`java.util.concurrent.locks.Lock`接口和`Condition`接口来解决这个问题。 `Lock`接口是Java并发库...

    java Lock接口详解及实例代码

    Java Lock接口是Java并发编程中一个重要的组成部分,它提供了一种更为灵活的锁机制,相比传统的`synchronized`关键字,Lock接口允许我们进行更细粒度的控制,包括可中断的锁等待、尝试获取锁以及定时等待等。...

    Java多线程中ReentrantLock与Condition详解

    Java多线程中ReentrantLock与Condition详解 ReentrantLock是Java多线程中一种高级的锁机制,它实现了Lock接口,提供了与synchronized相同的并发性和内存语义,但添加了一些特性,如锁投票、定时锁等候和可中断锁...

    Java多线程之ReentrantLock与Condition - 平凡希 - 博客园1

    Java中的`ReentrantLock`是Java并发包`java.util.concurrent.locks`中的一个高级锁机制,它是可重入的互斥锁,具有与`synchronized`关键字相似的同步性,但提供了更多的灵活性和控制功能。本篇文章将深入探讨`...

    生产者消费者Java—LOCK机制

    为了确保线程安全和有效率的数据交换,Java提供了多种同步机制,其中包括Lock接口及其实现,如ReentrantLock。本项目通过Lock机制实现了生产者-消费者的解决方案。 Lock接口是Java并发库(java.util.concurrent....

    Java Lock锁多线程中实现流水线任务

    使用Java Lock锁来实现流水线任务非常简单,我们可以使用ReentrantLock类来创建一个Lock对象,然后使用Condition对象来实现线程之间的通信。在上面的例子中,我们使用了三个Condition对象来实现三个线程之间的通信。...

    java 锁 Lock接口详解.docx

    在Java 1.5版本后,引入了`java.util.concurrent.locks`包,其中的`Lock`接口作为同步机制的新选择,弥补了`synchronized`关键字的一些局限性。下面将详细解释`Lock`接口以及与`synchronized`的区别。 `Lock`接口是...

    Java基于Lock的生产者消费者模型示例

    Java中基于Lock的生产者消费者模型是使用Lock和Condition来实现线程同步和通信的。 在本示例中,我们使用了ReentrantLock和Condition来实现生产者消费者模型。ReentrantLock是Java中的一种可重入锁,它可以多次锁定...

    Java并发编程(20)并发新特性-Lock锁和条件变量(

    本资源主要探讨了Java并发的新特性,特别是Lock锁和条件变量的使用。下面将详细阐述这两个概念以及如何在实际编程中应用它们。 Lock锁是Java并发库中的一个核心组件,位于java.util.concurrent.locks包下。相比传统...

    Java编程中实现Condition控制线程通信

    Java中的Lock接口及其实现,如ReentrantLock,提供了更高级的线程通信机制,其中包括Condition接口。 Condition接口是Java并发包java.util.concurrent.locks的一部分,它允许我们创建特定于锁的等待集合。相比于...

    Java使用Condition控制线程通信的方法实例详解

    Java 中,Condition 类是 Lock 接口的一个补充,它提供了一种机制来让线程等待某个条件的满足,然后继续执行。Condition 将同步监视锁方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与...

    Java学习资料-详解Condition的await和signal等待/通知机制

    在Java多线程编程中,`Condition`是Java并发包`java.util.concurrent.locks`中的一个接口,它提供了比`Object`类中的`wait()`、`notify()`和`notifyAll()`更加灵活和强大的线程间通信机制。`Condition`与`Lock`配合...

    Lock、Condition实现简单的生产者消费者模式示例

    在这个示例中,使用了Java的`java.util.concurrent.locks`包中的`Lock`接口和`Condition`接口来实现这一模式。`Lock`接口提供了比`synchronized`更精细的锁控制,而`Condition`接口则允许我们创建特定条件的等待队列...

Global site tag (gtag.js) - Google Analytics