---------------------- android培训、java培训、期待与您交流! ----------------------
8.用Lock实现线程间的通信:
当使用Lock对象来保证同步时,java提供了Condition类来保持线程间的协调运行。
在等待 Condition 时,可能发生“虚假唤醒”,所以, Condition 应该总是在一个循环中被等待。一个锁内部可以有多个Condition,即有多路等待和通知。
3.中示例加强:线程1循环5次,线程2循环10次,线程3循环20次。如此重复50次。注意编程构造方法。
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class TraditionalThreadCommunication {
public static void main(String[] args) {
final Business business = new Business();
new Thread(new Runnable() {
public void run() {
for (int i = 1; i <= 50; i++) {
business.thread1(i);System.out.println("1");
}
}
}).start();
new Thread(new Runnable() {
public void run() {
for (int i = 1; i <= 50; i++) {
business.thread2(i);System.out.println("2");
}
}
}).start();
new Thread(new Runnable() {
public void run() {
for (int i = 1; i <= 50; i++) {
business.thread3(i);System.out.println("3");
}
}
}).start();
}
}
// 封装资源
class Business {
Lock lock = new ReentrantLock();
Condition key1 = lock.newCondition();
Condition key2 = lock.newCondition();
Condition key3 = lock.newCondition();
int beShould = 1;
public void thread1(int i) {
lock.lock();
while (beShould != 1) {
try {
key1.await();
} catch (Exception e) {
}
}
for (int j = 1; j <= 5; j++) {
System.out.println("thread1 thread : " + j + ",loop: " + i);
}
beShould = 2;
key2.signal();System.out.println("Test");
lock.unlock();
}
public void thread2(int i) {
lock.lock();
while (beShould != 2) {
try {
key2.await();
} catch (Exception e) {
}
}
for (int j = 1; j <= 10; j++) {
System.out.println("thread2 thread: " + j + ",loop: " + i);
}
beShould = 3;
key3.signal();
lock.unlock();
}
public void thread3(int i) {
lock.lock();
while (beShould != 3) {
try {
key3.await();
} catch (Exception e) {
}
}
for (int j = 1; j <= 15; j++) {
System.out.println("thread3 thread: " + j + ",loop: " + i);
}
beShould = 1;
key1.signal();
lock.unlock();
}
}
9.Java中有队列的实现类,包括LinkedBlockingDeque和ArrayBlockingQueue类,他们都实现了BlockingQueue接口。其中,队列可以的take和put方法实现阻塞功能,示例如下:
public class BlockingQueueTest {
public static void main(String[] args) {
final BlockingQueue queue = new LinkedBlockingDeque(3);
//final BlockingQueue queue = new LinkedBlockingDeque(3);
for(int i=0;i<2;i++){
new Thread(){
public void run(){
while(true){
try {
Thread.sleep((long)(Math.random()*1000));
System.out.println(Thread.currentThread().getName() +
"准备放数据!"); queue.put(1);
System.out.println(Thread.currentThread().getName() + "已经放了数
据," + "队列目前有" + queue.size() + "个数据");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
new Thread(){
public void run(){
while(true){
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() +
"准备取数据!");
queue.take();
System.out.println(Thread.currentThread().getName() + "已经取走数
据," + "队列目前有" + queue.size() + "个数据"); } catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
}
用阻塞队列方法也可以实现类似3中例子的功能。思路:在main线程和sub线程中分别定义一个长度为1的阻塞队列。先在main线程中放入两个元素,main线程阻塞,所以sub线程运行。Sub线程运行达到要求后取出main线程中阻塞队列的一个元素,再在sub线程中放两个元素,sub线程阻塞,运行main线程。代码略。
10.Collections工具类提供了操作集合的一些功能,如(部分):
static <T> boolean addAll(Collection<? super T> c, T... elements)
将所有指定元素添加到指定 collection 中。
static <T> void copy(List<? super T> dest, List<? extends T> src)
将所有元素从一个列表复制到另一个列表。
static <T> boolean replaceAll(List<T> list, T oldVal, T newVal)
使用另一个值替换列表中出现的所有某一指定值。
static void reverse(List<?> list) 反转指定列表中元素的顺序。
static <T extends Comparable<? super T>> void sort(List<T> list)
根据元素的自然顺序 对指定列表按升序进行排序。
static <T> void sort(List<T> list, Comparator<? super T> c)
根据指定比较器产生的顺序对指定列表进行排序。
static void swap(List<?> list, int i, int j) 在指定列表的指定位置处交换元素。
还提供了一些静态方法吧集合包装成线程安全的集合。如下:
static <T> Collection<T> synchronizedCollection(Collection<T> c)
返回指定 collection 支持的同步(线程安全的)collection。
static <T> List<T> synchronizedList(List<T> list)
返回指定列表支持的同步(线程安全的)列表。
static <K,V> Map<K,V> synchronizedMap(Map<K,V> m)
返回由指定映射支持的同步(线程安全的)映射。
static <T> Set<T> synchronizedSet(Set<T> s)
返回指定 set 支持的同步(线程安全的)set。
static <K,V> SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V> m)
返回指定有序映射支持的同步(线程安全的)有序映射。
当然,软件包 java.util.concurrent下也有并发 Collection,详见API。
---------------------- android培训、java培训、期待与您交流! ----------------------