线程等待逻辑

时间:2016-02-22 17:48:45

标签: java multithreading

我有一个只有一组字符串的对象。我可以在任何时候为String添加名称。我设置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);
        }
    }
}

我将此作业提交给Runnable,如下所示,

public class FamilyWaiterThread implements Runnable {
    private FamilyGroup group;
    private final long MAX_WAITING_TIME = 1000 * 15;

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

    @Override
    public void run() {
        try {
            Thread.sleep(MAX_WAITING_TIME);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        group.displayFamilyMembers();
    }
}

此代码等待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");
    }
}

我正在添加名字&#34; Bret Lee&#34;产生新线程2秒后,新线程等待15秒并打印两个名称。输出

Shane Lee
Bret Lee

假设我添加名称&#34; Bret Lee&#34; 16秒后,

Thread.sleep(16000);
familyGroup1.addName("Bret Lee");

仅打印&#34; Shane Lee&#34;因为线程只等待15秒。 现在我想再添加一个功能。如果连续5秒没有添加名称并打印输出,我希望线程停止等待。如果在5秒内添加任何名称,则线程应继续侦听最多15秒。总而言之,我对组对象的最长等待时间是15秒。 15秒后,我肯定打印输出,如果没有名称添加至少5秒我打印输出。我无法找到实现这一点的方法。欢迎任何想法,因为我是多线程新手。< / p>

3 个答案:

答案 0 :(得分:0)

作为一个非常简单的解决方案,您可以在ToUniversalTime类中使用一个标志,表示是否已插入新数据。类似FamilyGroup的内容在public boolean HasSomethingNew = false方法中设置true,并在addName()方法中设置false
然后你需要在你的线程displayFamilyMembers方法中使用一个循环

run

答案 1 :(得分:0)

这是FamilyWaiterThread。我添加了一个带有变量名second(第二个线程)的线程实例..

设置打印15秒后,第二个Thread启动...如果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();
}

答案 2 :(得分:0)

最后我能够获得所需的输出。谢谢你们!

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;
    }
}