#Is while(true) a bad usage?

1 messages · Page 1 of 1 (latest)

warm rune
#

Using a while true to check if something is in a list is bad?

like

while(true) {
if(mylist.contain(x) {
//something
break;
}
continue;
}```
dry sandBOT
#

<@&987246399047479336> please have a look, thanks.

rich valve
#

it kinda is

#

whats wrong with a simple if?

#

why do you even need a loop

#

to check is something is in a list?

warm rune
# rich valve to check is something is in a list?

for example, imagine we have a message broker and we want to use it to ping another server,

sending the message ping and giving an id in the message

the other server return pong, how to get it?

at the method called when we got a message, add the response in a list (pong and his id)

after having sended the message, launche a while(true) to wait in the list the pong

peak pawn
#

but u already have a list

#

and a list has the contains method

#

so to figure out whether a list contains a given thing, u dont need any loops

#

u simply call the method and thats it

#

persons.contains(john)

warm rune
#

but the list will only contain our value after receiving the pong

rich valve
#

so you have two threads?

warm rune
#

yes

rich valve
#

well then you kinda need a similar structure

warm rune
#

what struct you mean?

rich valve
#

like usually you have a queue instead of a list

#

and then

while (true) {
    var item = queue.take();
}
warm rune
#

ah yes

#

so I can use a while(true)

#

why queue is better than a list?

rich valve
#

and a BlockingQueue so it blocks

rich valve
warm rune
#

there's not necessarily an order in my case, as I may have to collect other, heavier information, so some may arrive before others.

peak pawn
#

yeah u should have a global task queue that contains all incoming messages

#

and then a busy-loop as shown on that

warm rune
#

using a list don't make lag ?

#

(or concurent hashmap)

peak pawn
#

the stuff squid is talking about is exactly the classes made for these kind of things

#

so u should use it

#

its easier, faster, better, ...

#

it waits until it receives a new item and then u can process it

warm rune
terse niche
#

what are you storing in that map

warm rune
#

it depend

#

it can be an int

#

or an instance of a class

terse niche
#

i'm asking concretely

warm rune
#

I use it for some case

terse niche
#

because 90% of the time a queue is the right thing to use for communicating between threads

#

and if you just say "no, i'm using map" I can't intelligently give advice

#

because i don't understand why a map is involved

warm rune
#

lets say I should to store instance

rich valve
#

ig thats not really helpful

warm rune
#

okay I'll expalin more

#

explain*

warm rune
# rich valve ig thats not really helpful
public int sendPingMessageToServer2(Message m) {
(ping message contain an id)
calling message borker method to send message
Borker.sendMessage(m);

while(true) {
if(!ourmap.contain(id)) {
continue
}
System.out.println(ourmap.get(id).getPongLatence)
}
}

here we listen message received
public void onMessage(Message m) {
if(m.getType == MessageType.pong) {
ourmap.put(m)
}
}

that's more or less what I'm trying to do

terse niche
#

use a queue

#

ifmyou get a message you arent interested in, ignore it

warm rune
#

okay

#

and If I don't want to block the thread with my while true, I just have to do my while(true) in antother thread?

#

it will work?

rich valve
#

the while (true) kinda must be on a different thread anyways

warm rune
#

maybe I should use a completable future

rich valve
#

not sure what you mean

#

usually you basically have a different thread that has a while (true) with a blocking queue.take() call using a BlockingQueue

warm rune
#

I'm still not quite sure how to proceed, so I'll get back to you in a while to tell you what I think I've found.

terse niche
warm rune
# terse niche likely not

Here I add a completable future to execute the while in async and not blocking the thread, it can work like this?

public int sendPingMessageToServer2(Message m) {
(ping message contain an id)
calling message borker method to send message
Borker.sendMessage(m);
CompletableFuture f instancied;
f.thenaccept(()->{


while(true) {
if(!ourmap.contain(id)) {
continue
}
return ourMap.get(id);
}
})

Message pong = f.complete();
System.out.println(pong.getPongLatence)
}

here we listen message received
public void onMessage(Message m) {
if(m.getType == MessageType.pong) {
ourmap.put(m)
}
}

dry sandBOT
warm rune
#

with queue, when I .peek() I got the head, how can I get other objects?

#

I just loop it?

terse niche
#

?

#

this confuses me a lot

rich valve
terse niche
#

no, you most certainly do not need a CompletableFuture

warm rune
terse niche
#

sure

#

whatever

rich valve
#

thats why you run it in a different thread

warm rune
terse niche
#

one second. I will make you an example

warm rune
#

Ah yes I don't need you have reason

terse niche
#
import java.time.Duration;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;

record Message(int id, String payload) {}

void main() throws Exception {
    var q = new LinkedBlockingQueue<>();

    var stopBackgroundThread = new AtomicBoolean(false);
    var backgroundThread = Thread.startVirtualThread(() -> {
        while (!stopBackgroundThread.get()) {
            try {
                var msg = q.take();
                System.out.println("Got message: " + msg);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    });

    q.put(new Message(1, "Hello"));
    Thread.sleep(Duration.ofMillis(500));
    q.put(new Message(2, "World"));
    Thread.sleep(Duration.ofMillis(500));
    q.put(new Message(3, "!!!"));


    stopBackgroundThread.set(true);
    backgroundThread.join();

    System.out.println("DONE");
}
warm rune
#

But my code with completable future is correct ?

terse niche
#

no

warm rune
#

What is the problem ?

terse niche
#

well aside from you sending totally broken psuedocode

#

a CompletableFuture is not the correct mechanism for running a background thread

#

that is either a thread directly or an executor service

rich valve
#

its basically in the name of CompletableFuture

warm rune
#

Yes I know My question about just the code itself not his implémentation

warm rune
#

Every while should acces to every messages to get the correct

rich valve
#

Every while
?

#

its kinda not clear what you are doing

terse niche
#

Sorry man, your english is a bit broken

#

Are you implying that you have a single producer, but multiple consumer threads?

warm rune
#

Yes really I am.sorry

warm rune
terse niche
#

so you want to handle all of those pings in parallel?

warm rune
#

Yes we can say that

terse niche
#
import java.time.Duration;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;

record Ping() {}

void main() throws Exception {
    var q = new LinkedBlockingQueue<>();

    var stopBackgroundThread = new AtomicBoolean(false);
    var backgroundThread = Thread.startVirtualThread(() -> {
        while (!stopBackgroundThread.get()) {
            try {
                var msg = q.take();
                Thread.startVirtualThread(() -> {
                    try {
                        Thread.sleep(Duration.ofMillis(300));
                        System.out.println(msg);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                });
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    });

    q.put(new Ping());
    q.put(new Ping());
    q.put(new Ping());
    Thread.sleep(Duration.ofMillis(500));
    q.put(new Ping());
    q.put(new Ping());
    q.put(new Ping());
    Thread.sleep(Duration.ofMillis(500));
    q.put(new Ping());


    stopBackgroundThread.set(true);
    backgroundThread.join();

    System.out.println("DONE");
}
#

then you have one consumer read from the queue

#

and that consumer kicks off its own subtasks

warm rune
#

For this case Is not more simply to just while a .get(id) on concurenthashmap like I said (we dont have to loop all messages, de know what message we want)) I am not a pro but it seem most simpl?

terse niche
#

again, concurrent hash map is not the correct mechanism

#

it is not meant to be used as a queue

#

if you want to, read the documentation for it

#

your biggest problem is that you have no way to be "done" with a message

#

your loop that looks like this

#
while (true) {
    if (m.get(k)) {

    }
}
#

won't exit unless you break

#

which implies a thread per key

#

which is an extremely strange situation

#

i am not sure about the concurrency properties of .get - presumably it will work but unlike a q.take() which will probably yield your thread back to the scheduler

#

m.get(k) will make it a hot loop

warm rune
#

If I have 10 threads and the time it takes for one thread to retrieve its message from the head, the other 9 will be put on hold until the head is free, is this not a problem?

terse niche
#

It is not

#

Taking from a queue, presuming there are enough items to take, is fast

warm rune
#

Okay okay Its good
Thanks for your help