1、两个线程交替打印0-100如何实现(口述)
使用CyclicBarrier
package concurrent;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class Solution {
static CyclicBarrier barrier=new CyclicBarrier(2);
static volatile int num=1;
public static void main(String[] args) {
Thread t1=new Thread(new printEven());
Thread t2=new Thread(new printOdd());
t1.start();
t2.start();
}
public static class printOdd implements Runnable{
@Override
public void run() {
for(int i=0;i<50;i++){
while(num%2!=0);
System.out.println(num);
num++;
try{
barrier.await();
}catch (BrokenBarrierException | InterruptedException e){
e.printStackTrace();
}
}
}
}
public static class printEven implements Runnable{
@Override
public void run() {
for(int i=0;i<50;i++){
while(num%2==0);
System.out.println(num);
num++;
try{
barrier.await();
}catch (BrokenBarrierException | InterruptedException e){
e.printStackTrace();
}
}
}
}
}
用ReentrantLock
package concurrent;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class Print1To100 {
static ReentrantLock lock = new ReentrantLock();
static Condition condition = lock.newCondition();
static volatile int num = 1;
public static void main(String[] args) {
Thread t1 = new Thread(new PrintOdd());
Thread t2 = new Thread(new PrintEven());
t1.start();
t2.start();
}
public static class PrintOdd implements Runnable {
@Override
public void run() {
for (int i = 0; i < 50; i++) {
lock.lock();
try {
while (num % 2 == 0) {
condition.await();
}
System.out.println(num);
num++;
condition.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
public static class PrintEven implements Runnable {
@Override
public void run() {
for (int i = 0; i < 50; i++) {
lock.lock();
try {
while (num % 2 != 0) {
condition.await();
}
System.out.println(num);
num++;
condition.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
}
2、手写生产者消费者模型
https://blog.csdn.net/weixin_43232955/article/details/108159971
使用ReentrantLock
Message类
package concurrent;
public class Message {
private int id;
private Object message;
public Message(int id, Object message) {
this.id = id;
this.message = message;
}
public int getId() {
return id;
}
public Object getMessage() {
return message;
}
@Override
public String toString() {
return "Message{ " +
"id=" + id +
", message=" + message +
'}';
}
}
MessageQueue
package concurrent;
import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class MessageQueue {
private LinkedList<Message> queue = new LinkedList<>();
private int capacity;
public MessageQueue(int _capacity) {
capacity = _capacity;
}
ReentrantLock lock = new ReentrantLock();
Condition produce = lock.newCondition();
Condition consume = lock.newCondition();
public void put(Message m) {
lock.lock();
try {
while (queue.size() == capacity) {
System.out.println("队列已满,生产者等待...");
produce.await();
}
queue.offerLast(m);
System.out.println("生产消息" + m.toString());
consume.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void get() {
lock.lock();
try {
while (queue.isEmpty()) {
System.out.println("队列为空,消费者等待...");
consume.await();
}
Message m = queue.pollFirst();
System.out.println("消费消息:" + m.toString());
produce.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
Client
public class Client {
public static void main(String[] args) {
MessageQueue queue = new MessageQueue(2);
Runnable produce = () -> {
for (int i = 0; i < 10; i++) {
Message m = new Message(i, "消息" + i);
queue.put(m);
}
};
Runnable consume = () -> {
for (int i = 0; i < 10; i++) {
queue.get();
}
};
Thread t1 = new Thread(produce);
Thread t2 = new Thread(consume);
t1.start();
t2.start();
}
}