Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 多线程之间的对象共享_Java_Multithreading_Java 8 - Fatal编程技术网

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
条件队列将执行此任务。请阅读文档中的更多内容。