不讲武德(手动狗头):面试官上来就甩给我几道多线程代码题叫我手撕,我心里拔凉拔凉的~~~
【摘要】 不讲武德(手动狗头):面试官上来就甩给我几道多线程代码题叫我手撕,我心里拔凉拔凉的~~~
前言
栗花落香奈乎
女主真好看
两个线程,一个线程打印奇数,一个线程打印偶数
ReentrantLock + Condition 来实现
public class Main {
private static Lock lock = new ReentrantLock();
static Condition c1 = lock.newCondition();
static Condition c2 = lock.newCondition();
//数字
static volatile int num = 1;
public static void main(String[] args) {
//线程A
new Thread(() -> {
lock.lock();
try{
while (true) {
//如果是奇数
if (num % 2 == 1) {
System.out.println(Thread.currentThread().getName() + "打印奇数:\t" + num);
num++;
c2.signal();
c1.await();
}
}
}catch(Exception e){
e.printStackTrace();
}finally{
lock.unlock();
}
},"A").start();
//线程B
new Thread(() -> {
lock.lock();
try{
while (true) {
//如果是偶数
if (num % 2 == 0) {
System.out.println(Thread.currentThread().getName() + "打印偶数:\t" + num);
num++;
TimeUnit.SECONDS.sleep(1);
c1.signal();
c2.await();
}
}
}catch(Exception e){
e.printStackTrace();
}finally{
lock.unlock();
}
},"B").start();
}
}
三个线程打印ABC
public class Main {
private static int state = 0;
private static final Lock lock = new ReentrantLock();
public static void main(String[] args) {
//打印A
Thread a = new Thread(() -> {
while (true) {
lock.lock();
try{
if (state % 3 == 0) {
System.out.print("A");
state++;
}
}catch(Exception e){
e.printStackTrace();
}finally{
lock.unlock();
}
}
});
//打印B
Thread b = new Thread(() -> {
while (true) {
lock.lock();
try{
if (state % 3 == 1) {
System.out.print("B");
state++;
}
}catch(Exception e){
e.printStackTrace();
}finally{
lock.unlock();
}
}
});
//打印C
Thread c = new Thread(() -> {
while (true) {
lock.lock();
try{
if (state % 3 == 2) {
System.out.println("C");
TimeUnit.SECONDS.sleep(1);
state++;
}
}catch(Exception e){
e.printStackTrace();
}finally{
lock.unlock();
}
}
});
a.start();
b.start();
c.start();
}
}
线程打印A5次,B10次,C15次
public class Test01 {
private int number = 1;
private static Lock lock = new ReentrantLock();
static Condition c1 = lock.newCondition();
static Condition c2 = lock.newCondition();
static Condition c3 = lock.newCondition();
public void printNum(int num,Condition st,Condition start,int currentNum,int futureNum) {
lock.lock();
try{
while (number != currentNum) {
st.await();
}
for (int i = 1; i <= num; i++) {
System.out.println(Thread.currentThread().getName() + "\t" + i);
}
number = futureNum;
start.signal();
}catch(Exception e){
e.printStackTrace();
}finally{
lock.unlock();
}
}
public static void main(String[] args) {
Test01 test01 = new Test01();
new Thread(() -> {
for (int i = 0; i < 2; i++) {
test01.printNum(5,c1,c2,1,2);
}
},"AAA").start();
new Thread(() -> {
for (int i = 0; i < 2; i++) {
test01.printNum(10,c2,c3,2,3);
}
},"BBB").start();
new Thread(() -> {
for (int i = 0; i < 2; i++) {
test01.printNum(15,c3,c1,3,1);
}
},"CCC").start();
}
}
图没截完
创建水分子
实现两个方法生成一个水分子H2O,一个方法输出一个O,另一个方法输出一个H,水分子需要由2个H和一个O构成,
public class Main {
private static ReentrantLock lock = new ReentrantLock();
private static Condition c1 = lock.newCondition();
private static Condition c2 = lock.newCondition();
private static AtomicInteger num = new AtomicInteger(1);
public static void printH2() {
lock.lock();
try{
System.out.print("H");
if (num.intValue() % 2 == 0) {
c2.signal();
c1.await();
}else {
num.incrementAndGet();
printH2();
}
}catch(Exception e){
e.printStackTrace();
}finally{
lock.unlock();
}
}
public static void printO() {
lock.lock();
try{
System.out.println("O");
TimeUnit.SECONDS.sleep(1);
num.incrementAndGet();
c1.signal();
c2.await();
}catch(Exception e){
e.printStackTrace();
}finally{
lock.unlock();
}
}
public static void main(String[] args) {
new Thread(() -> {
while (true) {
printH2();
}
},"1").start();
new Thread(() -> {
while (true) {
printO();
}
},"2").start();
}
}
生产者、消费者阻塞普通版
public class Test01 {
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
private volatile int num = 0;
//生产者
public void produce() {
lock.lock();
try{
//如果不等于0,那么就不去生产
while (num != 0) {
condition.await();
}
//生产
num++;
System.out.println(Thread.currentThread().getName() + "\t生产:" + num);
//唤醒
condition.signal();
}catch(Exception e){
e.printStackTrace();
}finally{
lock.unlock();
}
}
//消费者
public void consumer() {
lock.lock();
try{
//如果恒等于0,那么就不能去消费
while (num == 0) {
condition.await();
}
//消费
num--;
System.out.println(Thread.currentThread().getName() + "\t消费:" + num);
TimeUnit.SECONDS.sleep(1);
//唤醒
condition.signal();
}catch(Exception e){
e.printStackTrace();
}finally{
lock.unlock();
}
}
public static void main(String[] args) {
Test01 test = new Test01();
new Thread(() -> {
while (true) {
test.produce();
}
},"A").start();
new Thread(() -> {
while (true) {
test.consumer();
}
},"B").start();
}
}
生产者、消费者阻塞队列版
public class Test01 {
public static void main(String[] args) {
//将阻塞队列容量初始化为5
MySource source = new MySource(new ArrayBlockingQueue<>(5));
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "\t 生产线程启动");
try {
source.myProduct();
}catch (Exception e) {
e.printStackTrace();
}
},"Product").start();
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "\t 消费线程启动");
System.out.println();
try {
source.myConsumer();
}catch (Exception e) {
e.printStackTrace();
}
},"Consumer").start();
//5秒后退出
try {
TimeUnit.SECONDS.sleep(5);
}catch (Exception e) {
e.printStackTrace();
}
System.out.println();
System.out.println("时间到,结束!");
source.stop();
}
}
class MySource {
private volatile boolean FLAG = true; // 默认开启 生产+消费
private AtomicInteger atomicInteger = new AtomicInteger();
//阻塞队列
BlockingQueue<String> blockingQueue = null;
public MySource(BlockingQueue<String> blockingQueue) {
this.blockingQueue = blockingQueue;
}
//生产者
public void myProduct() throws Exception {
String data = null;
boolean retValue;
while (FLAG) {
data = atomicInteger.incrementAndGet() + "";
//添加到阻塞队列,默认过期时间为2秒,offer方法返回的是 boolean值
retValue = blockingQueue.offer(data,2L, TimeUnit.SECONDS);
if (retValue) {
System.out.println(Thread.currentThread().getName() + "\t 插入队列成功" + data);
}else {
System.out.println(Thread.currentThread().getName() + "\t 插入队列失败" + data);
}
TimeUnit.SECONDS.sleep(1);
}
System.out.println(Thread.currentThread().getName() + "\t 停止生产");
}
//消费者
public void myConsumer() throws Exception {
String result = null;
while (FLAG) {
//两秒钟从队列中取不到就不放弃不取了
result = blockingQueue.poll(2L,TimeUnit.SECONDS);
//如果从队列中拿不到值,或者为 "",
if (null == result || "".equals(result)) {
FLAG = false;
System.out.println(Thread.currentThread().getName() + "\t 超时,消费退出");
return;
}
System.out.println(Thread.currentThread().getName() + "\t 消费队列成功" + result);
}
System.out.println(Thread.currentThread().getName() + "\t 停止消费");
}
public void stop() {
this.FLAG = false;
}
}
最后
我是 Code皮皮虾,未来的日子里会不断更新出对大家有益的博文,期待大家的关注!!!
创作不易,如果这篇博文对各位有帮助,希望各位小伙伴可以==一键三连哦!==,感谢支持,我们下次再见~~~
分享大纲
更多精彩内容分享,请点击 Hello World (●’◡’●)
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)