Java 线程等待逻辑
我有一个对象,它只有一组字符串。我可以在任何时候向字符串添加名称。我将5秒设置为完成添加要设置的名称的最大等待时间。之后,我将打印集合中的所有名称。因此,我为我的对象定义了以下类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
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;
}
}