I have encountered some challenge, I just want to confirm my knowledge is correct.
How are you going to implement this?
For example, if your program is written in Java the Sieve of Eratosthenes testing should run in one thread, and the Brute Force testing should run concurrently in a separate thread. Finally, your program should report the results of the benchmarking to the screen and exit.
Is it Something like this?
class TestMultitasking4{
public static void main(String args[]){
Thread t1=new Thread(){
public void run(){
System.out.println("task one");
}
};
Thread t2=new Thread(){
public void run(){
System.out.println("task two");
}
};
t1.start();
t2.start();
}
}
Your approach is correct although you might want to avoid creating anonymous classes by extending Thread inside the method.
The next step is to measure the elapsed time inside Runnable and use Thread.join() to wait for the threads to finish so you can display the results. Make sure to use the System.nanoTime() method and not currentTimeMillis() see here why.
If you feel like exploring Java standard library further take a look at things in the java.util.concurrent package e.g. a java.util.concurrent.ExecutorService.
This is incorrect. If you run the program it will just start 2 threads and exit immediately because your main thread will not wait for the termination of t1 and t2.
You should:
Collect the results of your threads (you need callable and futures)
Wait for the threads to terminate (Thread.join is the primitive)
There are lots of ways to achieve this without using Threads directly using higher-level abstractions . The simplest way is probably using CompletableFuture
public static void main(String[] args) {
CompletableFuture<Boolean> future1 = CompletableFuture.supplyAsync(() -> isPrime(42));
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> bruteForcePassword("encrypted"));
var prime = future1.join();
var pwd = future2.join();
System.out.println("Was prime:" + prime);
System.out.println("Password:" + pwd);
}
private static String bruteForcePassword(String s) {
return "Alph#Rome0";
}
private static boolean isPrime(long value) {
return false;
}
Related
I need a group of threads to run at the same time, and then another group of threads after that. For example, 10 threads start working, and then 10 or 15 other threads.
Of course, the first approach I've tried was to create a loop.
while (true) {
for (int i = 0; i < 10; i++) {
Thread thread = new Thread(
new Runnable() {
#Override
public void run() {
System.out.println("hi");
}
});
thread.start();
}
}
But the problem is when scenario like this happens: imagine if in first iteration, 8 threads finished their tasks, and 2 threads take longer time. The next 10 threads won't start until all 8 + 2 (completed and not completed) threads finish. while, I want an approach where 8 threads get replaced by 8 of waiting to start threads.
Bare Threads
It can be done using bare Thread and Runnable without diving into more advance technologies.
For that, you need to perform the following steps:
define your task (provide an implementation of the Runnable interface);
generate a collection of Threads creating based on this task);
start every thread;
invoke join() on every of these thread (note that firstly we need to start all threads).
That's how it might look like:
public static void main(String[] args) throws InterruptedException {
Runnable task = () -> System.out.println("hi");
int counter = 0;
while (true) {
System.out.println("iteration: " + counter++);
List<Thread> threads = new ArrayList<>();
for (int i = 0; i < 10; i++) {
threads.add(new Thread(task));
}
for (Thread thread : threads) {
thread.start();
}
for (Thread thread : threads) {
thread.join();
}
Thread.currentThread().sleep(1000);
}
}
Instead of managing your Threads manually, it definitely would be wise to look at the facilities provided by the implementations of the ExecutorService interfaces.
Things would be a bit earthier if you use Callable interface for your task instead of Runnable. Callable is more handy in many cases because it allows obtaining the result from the worker-thread and also propagating an exception if thing went wrong (as opposed run() would force you to catch every checked exception). If you have in mind something more interesting than printing a dummy message, you might find Callable to be useful for your purpose.
ExecutorService.invokeAll() + Callable
ExecutorService has a blocking method invokeAll() which expects a collection of the callable-tasks and return a list of completed Future objects when all the tasks are done.
To generate a light-weight collection of repeated elements (since we need to fire a bunch of identical tasks) we can use utility method Collections.nCopies().
Here's a sample code which repeatedly runs a dummy task:
ExecutorService executor = Executors.newWorkStealingPool();
while (true) {
executor.invokeAll(Collections.nCopies(10, () -> {
System.out.println("hi");
return true;
}));
}
To make sure that it does what expected, we can add a counter of iterations and display it on the console and Thread.currentThread().sleep() to avoid cluttering the output very fast (for the same reason, the number of tasks reduced to 3):
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newWorkStealingPool();
int counter = 0;
while (true) {
System.out.println("iteration: " + counter++);
executor.invokeAll(Collections.nCopies(3, () -> {
System.out.println("hi");
return true;
}));
Thread.currentThread().sleep(1000);
}
}
Output:
iteration: 0
hi
hi
hi
iteration: 1
hi
hi
hi
... etc.
CompletableFuture.allOf().join() + Runnable
Another possibility is to use CompletableFuture API, and it's method allOf() which expects a varargs of submitted tasks in the form CompletableFuture and return a single CompletableFuture which would be completed when all provided arguments are done.
In order to synchronize the execution of the tasks with the main thread, we need to invoke join() on the resulting CompletableFuture instance.
That's how it might be implemented:
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newWorkStealingPool();
Runnable task = () -> System.out.println("hi");
int counter = 0;
while (true) {
System.out.println("iteration: " + counter++);
CompletableFuture.allOf(
Stream.generate(() -> task)
.limit(3)
.map(t -> CompletableFuture.runAsync(t, executor))
.toArray(CompletableFuture<?>[]::new)
).join();
Thread.currentThread().sleep(1000);
}
}
Output:
iteration: 0
hi
hi
hi
iteration: 1
hi
hi
hi
... etc.
ScheduledExecutorService
I suspect you might interested in scheduling these tasks instead of running them reputedly. If that's the case, have a look at ScheduledExecutorService and it's methods scheduleAtFixedRate() and scheduleWithFixedDelay().
For adding tasks to threads and replacing them you can use ExecutorService. You can create it by using:
ExecutorService executor = Executors.newFixedThreadPool(10);
I have a custom asynchronous method and I know threads are executed randomly, but I want to execute them in order.
I want to solve the problem in the main() method.
I've tried Thread.sleep() but it's not useful.
public static void main(String[] args) throws Exception{
Monster monster = new Monster();
System.out.println(1);
monster.exe();
System.out.println(2);
monster.exe();
System.out.println(3);
monster.exe();
System.out.println(4);
}
Class Monster
class Monster {
public void exe() {
new Thread(() -> {
System.out.println("Monster...: "+ Thread.currentThread().getName());
}).start();
}
}
That's doable, but frankly pointless because such a "parallel" execution even less performant than sequential processing of these tasks.
If you are doing that just as an exercise, that's OK. Otherwise, either don't try to control the execution of these tasks or do it in a single-threaded environment.
For that, you might use method join():
public static void main(String[] args) throws InterruptedException {
Monster monster = new Monster();
System.out.println(1);
Thread thread1 = monster.exe();
thread1.join();
System.out.println(2);
Thread thread2 = monster.exe();
thread2.join();
System.out.println(3);
Thread thread3 = monster.exe();
thread3.join();
System.out.println(4);
}
Each call of join() will block the main thread until another thread (on which this method was invoked) isn't finished its job.
Note: method join() throws InterruptedException which is a checked exception and must be either handled with a try/catch or should be signified in the method declaration. I've deliberately chosen the second option in order to make the code simpler and keep focus on what it is intended to do. But you should know that it's not a good practice to add the throws clause to the declaration of the main() method.
A small change was done to the Monster class (method exe() returns a thread that has been created in order to be able to join on it).
public class Monster {
public Thread exe() {
Thread thread = new Thread(() -> {
System.out.println("Monster...: "+ Thread.currentThread().getName());
});
thread.start();
return thread;
}
}
Output
1
Monster...: Thread-0
2
Monster...: Thread-1
3
Monster...: Thread-2
4
Another way to do it is to extract the codes that you want to execute asynchronously into a separate Runnable :
Runnable newMonstorTask() {
return ()->System.out.println("Monster...: " + Thread.currentThread().getName());
}
And then use CompletableFuture to configure them to execute in order and asynchronously :
CompletableFuture.runAsync(newMonstorTask())
.thenRunAsync(newMonstorTask())
.thenRunAsync(newMonstorTask())
.thenRunAsync(newMonstorTask());
You can use CompletableFuture and then methods like thenApply().
Please look here: https://www.deadcoderising.com/java8-writing-asynchronous-code-with-completablefuture/
first what i am trying to do:
During the main thread execution i want to pause the main thread and start two parallel threads. As soon as both this parallel threads terminate, i'd like to start again with the main thread.
What i tried:
...
...
main thread is executing
...
...
CyclicBarrier barrier = new CyclicBarrier(2);
Thread child1 = new Thread(new ThreadBuilderTask(barrier,0));
Thread child2 = new Thread(new ThreadBuilderTask(barrier,1));
child1.start();
child2.start();
/* Now i'm expecting that child1 and child2 are running in parallel calling their fooFunction */
child1.join();
child2.join();
/*Now i'm expecting that main thread will wait for child1and also for child2 (that are running in parallel).*/
... main thread starts again after both child1 and child2 finished (reached the await of the barrier)
... (break point set here, never reached)
...
Thread builder custom class
public class ThreadBuilderTask implements Runnable{
private CyclicBarrier barrier;
private int index;
...setters and getters..
#Override
public void run() {
fooFunction(this.getIndex());
try {
this.getBarrier().await();
} catch (InterruptedException | BrokenBarrierException e) {
return;
}
}
public ThreadBuilderTask(CyclicBarrier barrier,int index){
this.barrier = barrier;
this.index = index;
}
public fooFunction(int index){
//Something taking some seconds to execute
}
It's not clear what is happening here but it is definetely not working. As soon as i call join everything stops and the main thread never restart. (I put a breakpoint after the joins to see when the main thread restarts).
Maybe there is a bit of confusion with these concepts and also i'm not sure if i need to use both the barrier and the joins or simply one of those techniques.
Thanks
Davide
As mentioned in the comments I'd also suggest to use CompletableFuture. A very basic example of your described requirements could look like this:
final Runnable runnable1 = ...;
final Runnable runnable2 = ...;
CompletableFuture<Void> future1 = CompletableFuture.runAsync(runnable1);
CompletableFuture<Void> future2 = CompletableFuture.runAsync(runnable2);
CompletableFuture.allOf(future1, future2).get(); // waits for both runnables to finish
You might want to add more/some exception handling to this example. But it should give an idea how this might work.
You may consider to use Java CompletableFuture to achieve the objective.
Using its functions like supplyAsync or runAsync you may start child threads and join their respective result in the end. Or you can simply let the main thread wait until the subsequent threads completes.
Recently I managed to implement a sample scatter-gather function using the same class.
Check Java Doc for more offerings and to find best available function: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html
I am wondering what happens in the following scenario:
Two threads are created:
Thread t1 = new Thread();
Thread t2 = new Thread();
Assume these just print out a string, the threads then call the .start() method:
t1.start();
t2.start():
My question is why do these threads print in a seemingly random order each time? I know threads execute concurrently but would t1 not always finish before t2 due to the sequential execution of the main process?
Calling start() on a Thread doesn't necessarily result in the thread running immediately after. It is possible for other things to happen in between your calling start() and the first line of your thread's run() method actually being run. And even once your run() is actually running, it's also possible that other things happen before, during, or after your run() method finishes.
In your question, you said: "assume these just print out a string" – here's an implementation of run() which does that:
public void run() {
System.out.println("my name is: " + getName());
}
So it's possible that t1 starts to run first, but before it actually calls System.out.println, t2 is allowed to execute and runs to completion, then t1 is resumed.
If this kind of behavior won't work for your use case, you'll need to add some kind of concurrency protection to coordinate how and when your threads run.
UPDATE:
To illustrate the unpredictable sequence of thread execution, run this code a few times and observe the output:
public class Example {
public static void main(String[] args) {
for (int k = 0; k < 10; k++) {
new TestThread(k).start();
}
}
}
class TestThread extends Thread {
private final int k;
TestThread(int k) {
this.k = k;
}
#Override
public void run() {
System.out.print(k + " ");
}
}
Here is the output from one of my local runs:
7 0 1 5 4 6 3 2 8 9
Thread.start() doesn't guarantee execution. It will just make the Thread state runnable and hand over to the Thread Scheduler. It is the Thread Scheduler which decides which thread to run when.
If you need code to execute in a defined order on multiple threads, you need to add synchronization code between those threads.
Otherwise, the system is free to schedule execution in any order it sees fit.
I am currently interested in learning about Multi-threading. I have written a piece of code. And my question is if this the correct way. I later want to implement this in another code of mine. My idea was to run multiple threads existing of the same class. So let's say 5 threads and they all have a runner class inside them. What I want to implement in another code, is that I want to run multiple browsers at once. So, I have a class Browser. And then I have 5 threads with the class Browser. And they are all working simultaneously but don't know each other, so they don't have any interaction with each other at all.
So is this idea OK then?
class Runner implements Runnable {
public void run() {
for(int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + " - " + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class BasisDemo {
public static void main(String[] args) {
Thread runner1 = new Thread(new Runner(), "Runner 1");
runner1.start();
Thread runner2 = new Thread(new Runner(), "Runner 2");
runner2.start();
}
}
Is this a good practise and does it support my idea?
Or is using multi-threading even unnecessary.
I don't know it for sure.
Thanks for helping me out.
So your idea would work. If you try this code below.
System.out.println(System.currentTimeMillis());
System.out.println(System.currentTimeMillis());
You will find that the time is actually the same, which mean these two lines are executed almost at the same time.
In term of your code:
Thread runner1 = new Thread(new Runner(), "Runner 1");
runner1.start();
Thread runner2 = new Thread(new Runner(), "Runner 2");
runner2.start();
These threads will be executed at almost the same time, that's why your idea will work.
To make it more accurate. You can switch your codes:
Thread runner1 = new Thread(new Runner(), "Runner 1");
Thread runner2 = new Thread(new Runner(), "Runner 2");
runner1.start();
runner2.start();
If you want to make the timing even more accurate. You can use CyclicBarrier. It allows a set of thread to wait for each other and start at the same time. Here is demo codes:
class Demo {
final CyclicBarrier barrier;
class Broswer implements Runnable {
Worker() { }
public void run() {
while (!done()) {
try {
// wait for other threads
barrier.await();
// work for something, in your case an hour, but how can you control that
// work....
// sleep for a certain time
sleep(certain time)
} catch (InterruptedException ex) {
return;
} catch (BrokenBarrierException ex) {
return;
}
}
}
}
public static main(String args[]) {
barrier = new CyclicBarrier(N);
for (int i = 0; i < N; ++i)
new Thread(new Broswer()).start();
// wait until all done, in your case, forever.
}
}
Sounds like you're on the right track. Each thread will have no reference of each other, since you defined them as separate objects. They would both be able to contain their own data, execute their own methods, completely independently of one another.
One way you could confirm they are executing simultaneously is to make your loop start from a random number, that way you will see the console output incrementing beginning from two different numbers. (i.e. 100, 50, 101, 102, 51, 52, ...)
What you have outlined is the most common way to create threads in Java, you can read more about it here if you have questions later on.
1 Thread, not 5
Or is using multi-threading even unnecessary. I don't know it for sure.
If using the same class to do the same work, then No, no need for 5 threads. You only need one thread to run a task daily in the background.
If you want a copy everyday of a daily newspaper, would you send one of you children to the store with a dollar in hand each morning or would you send five of your children each with a dollar in hand?
ScheduledExecutorService
Also, Java provide a slick facility for this kind of work where you are scheduling tasks to be done in the background regularly: ScheduledExecutorService. Search Stack Overflow for more info, and read the Oracle Tutorial on Executors.