Java 线程等待逻辑

Java 线程等待逻辑,java,multithreading,Java,Multithreading,我有一个对象,它只有一组字符串。我可以在任何时候向字符串添加名称。我将5秒设置为完成添加要设置的名称的最大等待时间。之后,我将打印集合中的所有名称。因此,我为我的对象定义了以下类 public class FamilyGroup { Set<String> names; private long id; public FamilyGroup(long id) { this.id = id; names = new HashSe

我有一个对象,它只有一组字符串。我可以在任何时候向字符串添加名称。我将5秒设置为完成添加要设置的名称的最大等待时间。之后,我将打印集合中的所有名称。因此,我为我的对象定义了以下类

public class FamilyGroup {
    Set<String> names;
    private long id;

    public FamilyGroup(long id) {
        this.id = id;
        names = new HashSet<String>();
    }

    public void addName(String name) {
        names.add(name);
    }

    public void displayFamilyMembers() {
        for (String string : names) {
            System.out.println(string);
        }
    }
}
此代码等待15秒,然后成功打印集合中的所有名称。这就是我测试它的方式

public class FamilyTest {
    public static void main(String[] args) throws InterruptedException {
        FamilyGroup familyGroup1 = new FamilyGroup(1L);
        familyGroup1.addName("Shane Lee");
        FamilyWaiterThread familyWaiterThread1 = new FamilyWaiterThread(familyGroup1);
        new Thread(familyWaiterThread1).start();
        Thread.sleep(2000);
        familyGroup1.addName("Bret Lee");
    }
}
我在生成新线程2秒后添加名称“Bret Lee”,新线程等待15秒并打印两个名称。输出为

Shane Lee
Bret Lee
假设我在16秒后加上“Bret Lee”这个名字

Thread.sleep(16000);
familyGroup1.addName("Bret Lee");
它只打印“Shane Lee”,因为线程只等待15秒。
现在我想再添加一个功能。如果连续5秒没有添加名称,我希望线程停止等待并打印输出。如果在5秒内添加了任何名称,则线程应继续侦听最多15秒。总之,我对组对象的最大等待时间是15秒。15秒后,我肯定会打印输出,如果在至少5秒钟内没有名字添加,我会打印输出。我想不出实现这一点的方法。欢迎任何想法,因为我是多线程新手。

作为一个非常简单的解决方案,您可以在
FamilyGroup
类中使用一个标志,指示是否插入了新数据。类似于
public boolean HasSomethingNew=false的东西,在
addName()方法中设置
true
,在
displayFamilyMembers
方法中设置
false

然后您需要在线程
run
方法中有一个循环,如下所示

@Override
public void run() {
    boolean EndThread = false;
    int WaitingRuns = 0;
    while(!EndThread){
        while(!group.HasSomethingNew && WaitingRuns < 3){
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            WaitingRuns++;
        }
        if(group.HasSomethingNew){
            group.displayFamilyMembers();
            WaitingRuns = 0;
        } else EndThread = true;
    }
}
@覆盖
公开募捐{
布尔EndThread=false;
int WaitingRuns=0;
而(!EndThread){
而(!group.HasSomethingNew&&WaitingRuns<3){
试一试{
睡眠(5000);
}捕捉(中断异常e){
e、 printStackTrace();
}
WaitingRuns++;
}
if(组HasSomethingNew){
group.displayFamilyMembers();
WaitingRuns=0;
}else-EndThread=true;
}
}

这是
家族waiterThread
。我添加了一个线程实例,其变量名为
second
(second-Thread)

打印set 15秒后,第二个
线程开始执行。。。如果add方法不停止,它将运行5秒。。它会打印,否则就不会。。是的,它是经过测试的

谢谢你。。。好问题,顺便说一句

public class FamilyWaiterThread implements Runnable {
private FamilyGroup group;
private final long MAX_WAITING_TIME = 1000 * 15;
Thread second = new Thread()
    {
        public void run()
        {
            try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
            System.out.println("Before adding");
            group.displayFamilyMembers();
        }
    };
FamilyWaiterThread(FamilyGroup group) {
    this.group = group;
}
FamilyWaiterThread(){}

@Override
public void run() {
        try {
            Thread.sleep(MAX_WAITING_TIME);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    group.displayFamilyMembers();
    second.start();
}
 }
这是FamilyGroup中的一个小变化

public void addName(String name) {
    names.add(name);
    new FamilyWaiterThread().second.stop();
}

最后,我能够得到所需的输出。谢谢大家

public class FamilyWaiterThread implements Runnable {
    private FamilyGroup group;
    private boolean hasSomthingNew = true;
    private final long MAX_WAITING_TIME = 1000 * 10;
    private final long MAX_INACTIVE_TIME = 1000 * 3;

    FamilyWaiterThread(FamilyGroup group) {
        this.group = group;
    }

    public boolean hasSomethingNew() {
        return hasSomthingNew;
    }

    public void setHasSomethingnew(boolean value) {
        hasSomthingNew = value;
    }

    @Override
    public void run() {
        long startTime = System.currentTimeMillis();
        while (!timeOut(startTime) && hasSomethingNew()) {
            hasSomthingNew = false;
            long currentTime = System.currentTimeMillis();
            if (((startTime + MAX_WAITING_TIME) - currentTime) < MAX_INACTIVE_TIME) {
                break;
            }
            try {
                Thread.sleep(MAX_INACTIVE_TIME);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        long afterWhileLoop = System.currentTimeMillis();
        System.out.println("Total waiting time " + (afterWhileLoop - startTime));
        group.displayFamilyMembers();
        System.out.println("__________________________________");
    }

    private boolean timeOut(long startTime) {
        long currentTime = System.currentTimeMillis();
        if ((currentTime - startTime) > MAX_WAITING_TIME) {
            return true;
        }
        return false;
    }
}
公共类FamilyWaiterThread实现可运行{
私人家庭组;
私有布尔hasSomthingNew=true;
私人最终最长等待时间=1000*10;
私人最终长时间最大不活动时间=1000*3;
FamilyWaiterThread(FamilyGroup组){
this.group=组;
}
公共布尔值hasSomethingNew(){
返回hasSomthingNew;
}
public void setHasSomethingnew(布尔值){
hasSomthingNew=值;
}
@凌驾
公开募捐{
long startTime=System.currentTimeMillis();
而(!timeOut(startTime)&&hasSomethingNew()){
hasSomthingNew=false;
长currentTime=System.currentTimeMillis();
if((开始时间+最大等待时间)-当前时间<最大非活动时间){
打破
}
试一试{
线程睡眠(最大非活动时间);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
long afterWhileLoop=System.currentTimeMillis();
System.out.println(“总等待时间”+(afterWhileLoop-startTime));
group.displayFamilyMembers();
System.out.println(“\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu”);
}
专用布尔超时(长启动时间){
长currentTime=System.currentTimeMillis();
如果((当前时间-开始时间)>最大等待时间){
返回true;
}
返回false;
}
}

您正在寻找的概念称为。在FamilyGroup的构造函数中创建两个看门狗计时器:第一个周期为15秒,第二个周期为5秒。每次添加名称时,都会重置后者。第一个计时器会滴答地打印名称。请注意,您需要适当的同步原语来避免数据竞争。
public class FamilyWaiterThread implements Runnable {
    private FamilyGroup group;
    private boolean hasSomthingNew = true;
    private final long MAX_WAITING_TIME = 1000 * 10;
    private final long MAX_INACTIVE_TIME = 1000 * 3;

    FamilyWaiterThread(FamilyGroup group) {
        this.group = group;
    }

    public boolean hasSomethingNew() {
        return hasSomthingNew;
    }

    public void setHasSomethingnew(boolean value) {
        hasSomthingNew = value;
    }

    @Override
    public void run() {
        long startTime = System.currentTimeMillis();
        while (!timeOut(startTime) && hasSomethingNew()) {
            hasSomthingNew = false;
            long currentTime = System.currentTimeMillis();
            if (((startTime + MAX_WAITING_TIME) - currentTime) < MAX_INACTIVE_TIME) {
                break;
            }
            try {
                Thread.sleep(MAX_INACTIVE_TIME);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        long afterWhileLoop = System.currentTimeMillis();
        System.out.println("Total waiting time " + (afterWhileLoop - startTime));
        group.displayFamilyMembers();
        System.out.println("__________________________________");
    }

    private boolean timeOut(long startTime) {
        long currentTime = System.currentTimeMillis();
        if ((currentTime - startTime) > MAX_WAITING_TIME) {
            return true;
        }
        return false;
    }
}