Java 多线程之间的对象共享
我的问题是:Java 多线程之间的对象共享,java,multithreading,java-8,Java,Multithreading,Java 8,我的问题是: 假设我有 class Person{ String name; int age; } 和2个螺纹T1、T2。T1组姓名,T2组年龄。 条件是,如果名称存在,则只设置年龄elsewait() 请协助如何使用Java解决此问题 谢谢, Rahul.您可以使用同步两个线程 在Person类中添加条件和重入锁定 import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Re
假设我有
class Person{
String name;
int age;
}
和2个螺纹T1、T2。T1组姓名
,T2组年龄
。条件是,如果名称存在,则只设置年龄else
wait()
请协助如何使用Java解决此问题 谢谢,
Rahul.您可以使用同步两个线程 在Person类中添加
条件
和重入锁定
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class Person {
private ReentrantLock lock;
private Condition nameCondition;
private String name;
private Integer age;
public Person() {
this.lock = new ReentrantLock();
this.nameCondition = lock.newCondition();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Condition getNameCondition() {
return nameCondition;
}
public ReentrantLock getLock() {
return lock;
}
}
名称线程设置名称和信号:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class NameRunnable implements Runnable{
private Person person;
private String name;
public NameRunnable(Person person, String name) {
this.person = person;
this.name = name;
}
@Override
public void run() {
ReentrantLock lock = person.getLock();
Condition condition = person.getNameCondition();
lock.lock();
try {
person.setName(name);
condition.signal();
} finally {
lock.unlock();
}
}
}
AgeThread在设置名称之前等待:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class AgeRunnable implements Runnable{
private Person person;
private Integer age;
public AgeRunnable(Person person, Integer age) {
this.person = person;
this.age = age;
}
@Override
public void run() {
ReentrantLock lock = person.getLock();
Condition condition = person.getNameCondition();
lock.lock();
try {
while (person.getName() == null) {
condition.await();
}
person.setAge(age);
} catch (InterruptedException e) {
// TODO
} finally {
lock.unlock();
}
}
}
在主线程中,使用以下参数启动NameThread和AgeThread:
public class Main {
public static void main(String[] args) throws InterruptedException {
Person person = new Person();
NameRunnable nameRunnable = new NameRunnable(person, "Test");
AgeRunnable ageRunnable = new AgeRunnable(person, 10);
new Thread(nameRunnable).start();
new Thread(ageRunnable).start();
}
}
您可以使用同步器同步两个线程
在Person类中添加条件
和重入锁定
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class Person {
private ReentrantLock lock;
private Condition nameCondition;
private String name;
private Integer age;
public Person() {
this.lock = new ReentrantLock();
this.nameCondition = lock.newCondition();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Condition getNameCondition() {
return nameCondition;
}
public ReentrantLock getLock() {
return lock;
}
}
名称线程设置名称和信号:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class NameRunnable implements Runnable{
private Person person;
private String name;
public NameRunnable(Person person, String name) {
this.person = person;
this.name = name;
}
@Override
public void run() {
ReentrantLock lock = person.getLock();
Condition condition = person.getNameCondition();
lock.lock();
try {
person.setName(name);
condition.signal();
} finally {
lock.unlock();
}
}
}
AgeThread在设置名称之前等待:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class AgeRunnable implements Runnable{
private Person person;
private Integer age;
public AgeRunnable(Person person, Integer age) {
this.person = person;
this.age = age;
}
@Override
public void run() {
ReentrantLock lock = person.getLock();
Condition condition = person.getNameCondition();
lock.lock();
try {
while (person.getName() == null) {
condition.await();
}
person.setAge(age);
} catch (InterruptedException e) {
// TODO
} finally {
lock.unlock();
}
}
}
在主线程中,使用以下参数启动NameThread和AgeThread:
public class Main {
public static void main(String[] args) throws InterruptedException {
Person person = new Person();
NameRunnable nameRunnable = new NameRunnable(person, "Test");
AgeRunnable ageRunnable = new AgeRunnable(person, 10);
new Thread(nameRunnable).start();
new Thread(ageRunnable).start();
}
}
您可以通过
CompletableFuture
实现这一点。就性能而言,代码可能不是最好的,但相对较短且易于维护:
public class Person {
final CompletableFuture<String> name = new CompletableFuture<>();
final CompletableFuture<Integer> age = new CompletableFuture<>();
public void setName(String value) {
System.out.println("Setting name to " + value);
name.complete(value);
System.out.println("Set name to " + value);
}
public void setAge(int value) {
System.out.println("Setting age to " + value);
// only set age when name is set, otherwise wait indefinitely
name.thenRun(() -> {
age.complete(value);
}).join();
System.out.println("Set age to " + value);
}
public String getName() {
return name.join();
}
public Integer getAge() {
return age.join();
}
private static void sleep(TimeUnit unit, int value) {
try {
Thread.sleep(unit.toMillis(value));
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IllegalStateException("interrupted");
}
}
static final ExecutorService executor = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws InterruptedException {
test("Thomas Edison", 1, 171, 2);
test("Elvis Presley", 2, 83, 1);
executor.shutdown();
}
static void test(final String name, final int secondsBeforeNameSet,
final int age, final int secondsBeforeAgeSet) throws InterruptedException {
final Person p = new Person();
executor.invokeAll(Arrays.asList(
Executors.callable(() -> {
sleep(TimeUnit.SECONDS, secondsBeforeAgeSet);
p.setAge(age);
}),
Executors.callable(() -> {
sleep(TimeUnit.SECONDS, secondsBeforeNameSet);
p.setName(name);
})
));
System.out.println("Person{ name:" + p.getName() + ", age:" + p.getAge() + "}");
}
}
公共类人物{
final CompletableFuture name=new CompletableFuture();
最终CompletableFuture年龄=新CompletableFuture();
公共void集合名(字符串值){
System.out.println(“将名称设置为”+值);
名称。完整(值);
System.out.println(“将名称设置为”+值);
}
公共无效设置(int值){
System.out.println(“将年龄设置为”+值);
//仅在设置名称时设置年龄,否则无限期等待
名称。然后运行(()->{
年龄。完成(价值);
}).join();
System.out.println(“将年龄设置为”+值);
}
公共字符串getName(){
返回name.join();
}
公共整数getAge(){
返回age.join();
}
专用静态无效睡眠(时间单位,int值){
试一试{
线程睡眠(单位为toMillis(值));
}
捕捉(中断异常e){
Thread.currentThread().interrupt();
抛出新的非法状态异常(“中断”);
}
}
静态最终执行器服务执行器=Executors.newFixedThreadPool(10);
公共静态void main(字符串[]args)引发InterruptedException{
测试(“托马斯·爱迪生”,1171,2);
测试(“猫王”,2,83,1);
executor.shutdown();
}
静态无效测试(最终字符串名、最终整数秒前重命名集、,
final int age,final int seconds beforeageset)抛出中断异常{
最终人员p=新人员();
executor.invokeAll(Arrays.asList(
执行人。可调用(()->{
睡眠(TimeUnit.SECONDS,secondsBeforeAgeSet);
p、 设置(年龄);
}),
执行人。可调用(()->{
睡眠(TimeUnit.SECONDS,secondsBeforRenameSet);
p、 集合名(名称);
})
));
println(“Person{name:+p.getName()+”,age:+p.getAge()+”);
}
}
您可以通过CompletableFuture
实现这一点。就性能而言,代码可能不是最好的,但相对较短且易于维护:
public class Person {
final CompletableFuture<String> name = new CompletableFuture<>();
final CompletableFuture<Integer> age = new CompletableFuture<>();
public void setName(String value) {
System.out.println("Setting name to " + value);
name.complete(value);
System.out.println("Set name to " + value);
}
public void setAge(int value) {
System.out.println("Setting age to " + value);
// only set age when name is set, otherwise wait indefinitely
name.thenRun(() -> {
age.complete(value);
}).join();
System.out.println("Set age to " + value);
}
public String getName() {
return name.join();
}
public Integer getAge() {
return age.join();
}
private static void sleep(TimeUnit unit, int value) {
try {
Thread.sleep(unit.toMillis(value));
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IllegalStateException("interrupted");
}
}
static final ExecutorService executor = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws InterruptedException {
test("Thomas Edison", 1, 171, 2);
test("Elvis Presley", 2, 83, 1);
executor.shutdown();
}
static void test(final String name, final int secondsBeforeNameSet,
final int age, final int secondsBeforeAgeSet) throws InterruptedException {
final Person p = new Person();
executor.invokeAll(Arrays.asList(
Executors.callable(() -> {
sleep(TimeUnit.SECONDS, secondsBeforeAgeSet);
p.setAge(age);
}),
Executors.callable(() -> {
sleep(TimeUnit.SECONDS, secondsBeforeNameSet);
p.setName(name);
})
));
System.out.println("Person{ name:" + p.getName() + ", age:" + p.getAge() + "}");
}
}
公共类人物{
final CompletableFuture name=new CompletableFuture();
最终CompletableFuture年龄=新CompletableFuture();
公共void集合名(字符串值){
System.out.println(“将名称设置为”+值);
名称。完整(值);
System.out.println(“将名称设置为”+值);
}
公共无效设置(int值){
System.out.println(“将年龄设置为”+值);
//仅在设置名称时设置年龄,否则无限期等待
名称。然后运行(()->{
年龄。完成(价值);
}).join();
System.out.println(“将年龄设置为”+值);
}
公共字符串getName(){
返回name.join();
}
公共整数getAge(){
返回age.join();
}
专用静态无效睡眠(时间单位,int值){
试一试{
线程睡眠(单位为toMillis(值));
}
捕捉(中断异常e){
Thread.currentThread().interrupt();
抛出新的非法状态异常(“中断”);
}
}
静态最终执行器服务执行器=Executors.newFixedThreadPool(10);
公共静态void main(字符串[]args)引发InterruptedException{
测试(“托马斯·爱迪生”,1171,2);
测试(“猫王”,2,83,1);
executor.shutdown();
}
静态无效测试(最终字符串名、最终整数秒前重命名集、,
final int age,final int seconds beforeageset)抛出中断异常{
最终人员p=新人员();
executor.invokeAll(Arrays.asList(
执行人。可调用(()->{
睡眠(TimeUnit.SECONDS,secondsBeforeAgeSet);
p、 设置(年龄);
}),
执行人。可调用(()->{
睡眠(TimeUnit.SECONDS,secondsBeforRenameSet);
p、 集合名(名称);
})
));
println(“Person{name:+p.getName()+”,age:+p.getAge()+”);
}
}
这有点难。我想你只需要把person对象作为一个单身汉。共享您的代码,以便清楚地知道您要做什么!简单的wait notifyAll
条件队列将执行此任务。阅读文档中的更多内容。这有点需要继续。我想你只需要将person对象作为一个单体。共享您的代码,以便清楚地知道您要做什么!简单的wait notifyAll
条件队列将执行此任务。请阅读文档中的更多内容。