gpt4 book ai didi

java - java中线程通信的锁与条件

转载 作者:行者123 更新时间:2023-11-30 06:17:34 26 4
gpt4 key购买 nike

我是一个java初学者,我在学习时写了下面的代码Thread在Java中。我想,如果我锁定Resource.set()并注释掉Lock.unlock()Resource.out() 中的代码无法执行,因为当我想执行 out 方法时无法解锁。顺便说一句,我是否注释掉 set() 中的解锁或在 out() ,程序将这样执行:

Thread[Thread-1,5,main]....Produce....chicken1
Thread[Thread-2,5,main]....Consume..........chicken1
Thread[Thread-0,5,main]....Produce....chicken2
Thread[Thread-3,5,main]....Consume..........chicken2 ......

我想了很久,也想不明白。我刚刚学习,可能理解有误,希望大家帮忙。 请原谅我糟糕的英语。非常感谢。我的代码在这里:

package Thread;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ThreadStudying {

public static void main(String[] args) {
Resource r = new Resource();
Thread t0 = new Thread(new Producer(r));
Thread t1 = new Thread(new Producer(r));
Thread t2 = new Thread(new Consumer(r));
Thread t3 = new Thread(new Consumer(r));

t0.start();
t1.start();
t2.start();
t3.start();
}

static class Resource {
private String name;
private int count = 1;
boolean isOut = false;

Lock lock = new ReentrantLock();
Condition pro_con = lock.newCondition();
Condition consu_con = lock.newCondition();

public void set(String name) {
lock.lock();
try {
while (isOut) {
try {
pro_con.await();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}

this.name = name + count;
System.out.println(Thread.currentThread() + "....Produce...." + this.name);
count++;

isOut = true;
consu_con.signal();
}
finally {
lock.unlock();
}
}

public void out() {
lock.lock();
try {
while (!isOut) {
try {
consu_con.await();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}

System.out.println(Thread.currentThread() + "....Consume.........." + this.name);

isOut = false;
pro_con.signal();
}
finally {
//lock.unlock();
}
}
}

static class Producer implements Runnable {
Resource r;

Producer(Resource r) {
this.r = r;
}

public void run() {
while (true) {
r.set("chicken");

try {
Thread.sleep(500);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

static class Consumer implements Runnable {
Resource r;

Consumer(Resource r) {
this.r = r;
}


@Override
public void run() {
while (true) {
r.out();
try {
Thread.sleep(500);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}

最佳答案

在生产者和消费者中,您都重复调用lock.await

while (true) {
//
}

来自doc ,当您调用lock.await时:

The lock associated with this Condition is atomically released

所以,无论你是否注释掉lock.unlock,生产者和消费者都不会被阻塞。

P.S.使用下面的代码来记录有关获取和释放锁定的更多详细信息:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ThreadStudying {

public static void main(String[] args) {
Resource r = new Resource();
Thread t0 = new Thread(new Producer(r), "Producer 1");
Thread t1 = new Thread(new Producer(r), "Producer 2");
Thread t2 = new Thread(new Consumer(r), "Consumer 1");
Thread t3 = new Thread(new Consumer(r), "Consumer 2");

t0.start();
t1.start();
t2.start();
t3.start();
}

static class Resource {
private String name;
private int count = 1;
boolean isOut = false;

Lock lock = new ReentrantLock();
Condition pro_con = lock.newCondition();
Condition consu_con = lock.newCondition();

public void set(String name) {
System.out.println(Thread.currentThread() + "before lock");
lock.lock();
System.out.println(Thread.currentThread() + "get lock");
try {
while (isOut) {
try {
System.out.println(Thread.currentThread() + "release lock");
pro_con.await();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}

this.name = name + count;
System.out.println(Thread.currentThread() + "....Produce...." + this.name);
count++;

isOut = true;
consu_con.signal();
}
finally {

}
}

public void out() {
System.out.println(Thread.currentThread() + "before lock");
lock.lock();
System.out.println(Thread.currentThread() + "get lock");
try {
while (!isOut) {
try {
System.out.println(Thread.currentThread() + "release lock");
consu_con.await();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}

System.out.println(Thread.currentThread() + "....Consume.........." + this.name);

isOut = false;
pro_con.signal();
}
finally {
//lock.unlock();
}
}
}

static class Producer implements Runnable {
Resource r;

Producer(Resource r) {
this.r = r;
}

public void run() {
while (true) {
r.set("chicken");

try {
Thread.sleep(500);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

static class Consumer implements Runnable {
Resource r;

Consumer(Resource r) {
this.r = r;
}


@Override
public void run() {
while (true) {
r.out();
try {
Thread.sleep(500);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}

关于java - java中线程通信的锁与条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48879440/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com