---------------------- 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培訓、期待與您交流! ----------------------