1、ReentrantLock、Condition
public class test {
private int outPutNum = 1;
boolean t1_run_flag = true;
@Test
public void main() {
Lock lock = new ReentrantLock();
Condition condThread1 = lock.newCondition();
Condition condThread2 = lock.newCondition();
Thread thread_1 = new Thread() {
public void run() {
try {
lock.lock();
while (outPutNum <= 100) {
if (!t1_run_flag) {
condThread1.await();
}
if(outPutNum > 100) {
break;
}
System.out.println("thread_1:" + outPutNum);
outPutNum++;
t1_run_flag = false;
condThread2.signal();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
};
Thread thread_2 = new Thread() {
public void run() {
try {
lock.lock();
while (outPutNum <= 100) {
if (t1_run_flag) {
condThread2.await();
}
if(outPutNum > 100) {
break;
}
System.out.println("thread_2:" + outPutNum);
outPutNum++;
t1_run_flag = true;
condThread1.signal();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
};
thread_1.start();
thread_2.start();
}
}
2、CountDownLatch
public class ToolDemo1 {
private int[] nums;
public ToolDemo1(int line) {
nums = new int[line];
}
public void calc(String line, int index, CountDownLatch latch) {
String[] nus = line.split(",");
int total = 0;
for(String num : nus) {
total += Integer.parseInt(num);
}
nums[index] = total;
System.out.println(Thread.currentThread().getName() + "執行計算任務" + line + "結果爲:" + total);
latch.countDown();
}
public void sum() {
System.out.println("彙總線程開始執行...");
int total = 0;
for(int i = 0; i < nums.length; i++) {
total += nums[i];
}
System.out.println("最終的結果爲:" + total);
}
public static void main(String[] args) {
List<String> contents = readFile();
int lineCount = contents.size();
CountDownLatch latch = new CountDownLatch(lineCount);
ToolDemo1 d = new ToolDemo1(lineCount);
for(int i = 0; i < lineCount; i++) {
final int j = i;
new Thread(new Runnable() {
@Override
public void run() {
d.calc(contents.get(j), j, latch);
}
}).start();
}
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
d.sum();
}
private static List<String> readFile() {
List<String> contents = new ArrayList<>();
String line = null;
BufferedReader br = null;
try {
String root = System.getProperty("user.dir");
br = new BufferedReader(new FileReader(root + "/nums.txt"));
while ((line = br.readLine()) != null) {
contents.add(line);
}
}catch (Exception e) {
e.printStackTrace();
} finally {
if(br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return contents;
}
}
3、CyclicBarrier(與CountDownLatch區別是採用加計數,await()使計數+1,可以重置)
public class ToolDemo2 {
Random random = new Random();
public void meeting(CyclicBarrier barrier) {
try {
Thread.sleep(random.nextInt(2000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "到達會議室,等待會議開始...");
try {
barrier.await();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ToolDemo2 toolDemo2 = new ToolDemo2();
CyclicBarrier barrier = new CyclicBarrier(10, new Runnable() {
@Override
public void run() {
System.out.println("開始開會...");
}
});
for(int i = 0; i < 10; i++) {
new Thread(new Runnable() {
@Override
public void run() {
toolDemo2.meeting(barrier);
}
}).start();
}
}
}
3、Semaphore
public class ToolDemo3 {
public void method(Semaphore semaphore) {
try {
semaphore.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " is run...");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
semaphore.release();
}
public static void main(String[] args) {
ToolDemo3 toolDemo3 = new ToolDemo3();
Semaphore semaphore = new Semaphore(10);
for(int i = 0; i < 50; i++) {
new Thread(new Runnable() {
@Override
public void run() {
toolDemo3.method(semaphore);
}
}).start();
}
}
}
4、Exchanger
public class ToolDemo4 {
public void exchangeA(Exchanger<String> exch) {
System.out.println("exchangeA 方法執行...");
try {
System.out.println("exchangeA 線程正在抓取數據...");
Thread.sleep(2000);
System.out.println("exchangeA 線程抓取數據結束...");
} catch (InterruptedException e) {
e.printStackTrace();
}
String res = "12345";
try {
System.out.println("等待對比結果...");
exch.exchange(res);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void exchangeB(Exchanger<String> exch) {
System.out.println("exchangeB 方法執行...");
try {
System.out.println("exchangeB 線程正在抓取數據...");
Thread.sleep(2000);
System.out.println("exchangeB 線程抓取數據結束...");
} catch (InterruptedException e) {
e.printStackTrace();
}
String res = "12345";
try {
String value = exch.exchange(res);
System.out.println("開始進行比對...");
System.out.println("對比結果: " + value.equals(res));
exch.exchange(res);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ToolDemo4 toolDemo4 = new ToolDemo4();
Exchanger<String> exch = new Exchanger<>();
new Thread(new Runnable() {
@Override
public void run() {
toolDemo4.exchangeA(exch);
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
toolDemo4.exchangeB(exch);
}
}).start();
}
}
5、ForkJoin
public class ToolDemo5 extends RecursiveTask<Integer> {
private int begin;
private int end;
public ToolDemo5(int begin, int end) {
this.begin = begin;
this.end = end;
}
@Override
protected Integer compute() {
int sum = 0;
// 拆分任務
if(end - begin <= 2) {
// 計算
for(int i = begin; i <= end; i++) {
sum += i;
}
return sum;
} else {
// 拆分
ToolDemo5 d1 = new ToolDemo5(begin, (begin + end) / 2);
ToolDemo5 d2 = new ToolDemo5((begin + end) / 2 + 1, end);
//執行任務
d1.fork();
d2.fork();
Integer res1 = d1.join();
Integer res2 = d2.join();
sum = res1 + res2;
}
return sum;
}
public static void main(String[] args) throws Exception {
ForkJoinPool pool = new ForkJoinPool();
Future<Integer> feature = pool.submit(new ToolDemo5(1, 100));
System.out.println("...");
System.out.println("計算的值爲:" + feature.get());
}
}
6、BlockingQueue
public class EShop implements Shop{
private final int MAX_COUNT = 10;
private BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(MAX_COUNT);
@Override
public void push() {
try {
queue.put(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void take() {
try {
queue.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void size() {
while(true) {
System.out.println("當前隊列的長度:" + queue.size());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class PushTarget implements Runnable {
private Shop eShop;
public PushTarget(Shop eShop) {
this.eShop = eShop;
}
@Override
public void run() {
while (true) {
eShop.push();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public interface Shop {
void push();
void take();
void size();
}
public class TakeTarget implements Runnable {
private Shop eShop;
public TakeTarget(Shop eShop) {
this.eShop = eShop;
}
@Override
public void run() {
while (true) {
eShop.take();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class ToolDemo6 {
public static void main(String[] args) {
Shop eShop = new EShop();
TakeTarget takeTarget = new TakeTarget(eShop);
PushTarget pushTarget = new PushTarget(eShop);
new Thread(pushTarget).start();
new Thread(pushTarget).start();
new Thread(pushTarget).start();
new Thread(pushTarget).start();
new Thread(pushTarget).start();
new Thread(takeTarget).start();
new Thread(takeTarget).start();
new Thread(takeTarget).start();
new Thread(takeTarget).start();
new Thread(takeTarget).start();
new Thread(new Runnable() {
@Override
public void run() {
eShop.size();
}
}).start();
}
}
7、StampedLock(與ReetrantReadWriteLock區別在於這個是樂觀鎖)
public class ToolDemo7 {
private int balance;
private StampedLock lock = new StampedLock();
public void conditionReadWrite(int value) {
// 首先判斷balance是否滿足條件
long stamp = lock.readLock();
while(balance > 0) {
long writeStamp = lock.tryConvertToWriteLock(stamp);
// 成功轉換成寫鎖
if(writeStamp != 0) {
stamp = writeStamp;
balance += value;
break;
} else {
// 沒有轉換成寫鎖,這裏需要首先釋放讀鎖,然後在拿到寫鎖
lock.unlockRead(stamp);
// 獲取寫鎖
stamp = lock.writeLock();
}
}
lock.unlock(stamp);
}
public void optimisticRead() {
long stamp = lock.tryOptimisticRead();
int res = balance;
// 這裏可能會出現寫操作,因此要進行判斷
if(!lock.validate(stamp)) {
// 重新獲取讀鎖
long readStamp = lock.readLock();
res = balance;
stamp = readStamp;
}
lock.unlockRead(stamp);
}
public void read() {
long stamp = lock.readLock();
int res = balance;
// 釋放讀鎖
lock.unlockRead(stamp);
}
public void write(int value) {
long stamp = lock.writeLock();
balance += value;
lock.unlockWrite(stamp);
}
}