I wrote the below code trying to run two threads for calling a function in a for loop, but the results have the same time as if I ran it sequentially without multiple threads. Any thoughts why the multithreading here is not working? Is there a better way to do it? Like for example if I wanted to have 10 threads, using my code this will mean I have to create 10 duplicate run() functions when creating the thread, I wonder if there is an easier way to set the number of threads? Also is it possible to create a number of threads depending on the loop counter so that each loop a thread is created to finish it so if I had 10 loops then 10 threads will run concurrently to finish the processing very fast?
private Thread t1 = new Thread(){
public void run(){
for (int i = 0; i < 2; i++)
{
try {
myfn(i);
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
private Thread t2 = new Thread(){
public void run(){
for (int i = 2; i < 4; i++)
{
try {
myfn(i);
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
public Results getResults() throws IOException, SocketTimeoutException {
t1.start();
t2.start();
try {
t1.join(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
t2.join(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
For running the same task across multiple threads, you're probably looking for a thread pool. Java provides a ThreadPoolExecutor for this.
Here is an introduction to Java concurrency with the following example:
ExecutorService executor = Executors.newFixedThreadPool(1);
Future<Integer> future = executor.submit(() -> {
try {
TimeUnit.SECONDS.sleep(2);
return 123;
}
catch (InterruptedException e) {
throw new IllegalStateException("task interrupted", e);
}
});
future.get(1, TimeUnit.SECONDS);
That example specifically creates a pool with only a single thread, but the parameter to Executors.newFixedThreadPool controls how many threads will be used.
I'm not sure from your original question why you think two threads aren't being utilized.
public class MyThead extend Thread{
private int initValue = 0;
private int upperBound = 0;
public MyThread(int init, int ub){
this.initValue = init;
this.upperBound = ub;
}
public void run(){
for(int i = init; i < upperBound; i++){
myfn(i);
}
}
}
Create threads and start them:
List<Thread> threads = new ArrayList<>();
threads.add(new MyThread(0,2));
threads.add(new MyThread(2,4));
for(Thread t: threads){
t.start()
}
for(Thread t: threads){
t.join();
}
I wrote the below code trying to run two threads for calling a function in a for loop, but the results have the same time as if I ran it sequentially without multiple threads.
There are many reasons why that can happen although it's hard to know what is going on without seeing the myfn(...) code. Here are some possible reasons:
It could be that myfn runs so quickly that running it in different threads isn't going to be any faster.
It could be that myfn is waiting on some other resource in which case the threads can't really run concurrently.
It could be that myfn is blocking on IO (network or disk) and even though you are doing 2 (or more) of them at a time, the disk or the remote server can't handle the increased requests any faster.
Is there a better way to do it? Like for example if I wanted to have 10 threads, using my code this will mean I have to create 10 duplicate run() functions...
The right thing to do here is to create your own class which takes the lower and upper bounds. The right way to do this is to implement Runnable, not extend Thread. Something like:
public class MyRunnable implements Runnable {
private final int start;
private final int end;
public MyRunnable(int start, int end) {
this.start = start;
this.end = end;
}
public void run() {
for (int i = start; i < end; i++) {
myfn(i);
}
}
}
You can then either start the threads by hand or use an ExecutorService which makes the thread maintenance a lot easier:
// this will start a new thread for every job
ExecutorService threadPool = Executors.newCachedThreadPool();
threadPool.submit(new MyRunnable(0, 2));
threadPool.submit(new MyRunnable(2, 4));
// once you've submitted your last task, you shutdown the pool
threadPool.shutdown();
// then we wait until all of the tasks have run
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
You don't need to copy your threads / loop 10 times, just take the logic and use it appropriately.
public class ExampleThread extends Thread {
private final int start, iterations;
public ExampleThread(int start, int iterations) {
this.start = start;
this.iterations = iterations;
}
#Override public void run() {
for (int i = 0; i < iterations; i++) {
myfn(start + i);
}
}
}
int iterations = 2;
List<Thread> threads = new ArrayList<>();
for (int threadId = 0; threadId < 10; threadId++) {
threads.add(new ExampleThread(threadId * iterations, iterations));
}
threads.forEach(Thread::start);
threads.forEach(t -> {
try {
t.join(0);
} catch (Exception e) {
e.printStackTrace(System.err);
}
});
Related
I need to execute a single task by multiple threads, such that when the first thread finishes and before any other thread finishes, all the threads are stopped and start the same task all over again. This should be performed n times.
My attempt is using Callable<V> and the method invokeAny() (that is why I use the set) but not sure how to accomplish the goal.
ExecutorService executor = Executors.newFixedThreadPool(10);
Callable<String> task = () -> {
someTask();
return "";
};
Set<Callable<String>> tasks = new HashSet<>();
IntStream.range(0, n).forEach(i -> {
tasks.add(task);
executor.submit(task);
});
How to finish this? or any better solution?
Here's one suggestion:
class Task implements Callable<Integer> {
private final static Random RND = new Random();
#Override
public Integer call() throws Exception {
try {
// Work on task for a random duration
Thread.sleep(RND.nextInt(5000));
} catch (InterruptedException e) {
System.err.println("I was interrupted."
+ "Someone else probably solved the task before me.");
return -1;
}
// Return some dummy value
return RND.nextInt();
}
}
class Scratch {
public static void main(String[] args) throws InterruptedException {
final int numWorkers = 3; // number of tasks to run in parallel
ExecutorService executor = Executors.newFixedThreadPool(numWorkers);
// Solve task 5 times. (Change it to while (true) { ...} if you like.)
for (int i = 0; i < 5; i++) {
CompletionService<Integer> completionService =
new ExecutorCompletionService<>(executor);
Future<?>[] futures = new Future<?>[numWorkers];
for (int j = 0; j < numWorkers; j++) {
futures[j] = completionService.submit(new Task());
}
Future<Integer> firstToComplete = completionService.take();
try {
Integer result = firstToComplete.get();
System.err.println("We got a result: " + result);
} catch (ExecutionException e) {
// Should not happen. Future has completed.
}
// Cancel all futures (it doesn't matter that we're cancelling
// the one that has already completed).
for (int j = 0; j < numWorkers; j++) {
futures[j].cancel(true);
}
}
executor.shutdown();
}
}
If the task you're solving does not respond to interrupts, passing true to cancel(...) won't help. In that case I'd suggest you do the following changes:
Create an AtomicBoolean done variable in the outer for loop.
Pass this to the constructor to Task and save it in a field in Task.
In the task solving process, check done flag ever so often, and cancel the attempt if done is true.
Instead of calling cancel on the tasks after the first result is in, set done to true and wait for the other threads to return.
why the result is always 101?
I think the result should be random since is shareVar not thread safe
public class ThreadQuestion
{
public static int shareVar = 1;
public static void main(String[] args) throws InterruptedException
{
ExecutorService threadPool = Executors.newFixedThreadPool(20);
for(int i = 0; i < 100; i++)
{
threadPool.execute(new Runnable()
{
#Override
public void run()
{
shareVar++;
}
});
}
//wait for other thread finish
Thread.sleep(5000);
System.out.println("shareVar is " + shareVar );
threadPool.shutdown();
}
}
Your concurrent tasks run practically sequential because CPU extremely fast so your task(increment) will run really quick. Your loop execute a bit slower so when you add new task old task will be already executed. Moreover concurrency it's always about theory of chances and 100 it's a small value for getting glitches for this short task.
You should expand loop to bigger value for example to 10000 or even 10000 or just put a tiny delay in your code like this:
for (int i = 0; i < 100; i++) {
threadPool.execute(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(10);
shareVar++;
} catch (InterruptedException ex) {
Logger.getLogger(ThreadQuestion.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
in this case you'll really try to run several threads in the same time and result will change from 101 to about a hundred.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
A final counter in a for loop?
Below is the code I'm currently running. I'd like to be able to pass the iterator i into the new Runnable() code. I know I usually need the make variables final in order to pass into an inner class, but that ruins the effect of the iterator. I know normally I could try to make the Runnable inner class a true class (excuse my lack of terminology), but then I'd lose the effects of the CountDownLatches.
private long generateThreads(int cores){
if (cores <= 0)
cores = Runtime.getRuntime().availableProcessors();
System.out.println("Using " + cores + " threads for processing");
final ExecutorService exec = Executors.newFixedThreadPool(cores);
final CountDownLatch ready = new CountDownLatch(cores);
final CountDownLatch start = new CountDownLatch(1);
final CountDownLatch done = new CountDownLatch(cores);
for (int i = 1; i <= cores; i++){
exec.execute(new Runnable(){
public void run(){
ready.countDown();
try{
start.await();
//do work
}
} catch (InterruptedException e){
Thread.currentThread().interrupt();
} finally{
done.countDown();
exec.shutdown();
}
}
});
}
long startTime = 0;
try{
ready.await();
startTime = System.nanoTime();
start.countDown();
done.await();
} catch (InterruptedException e){
e.printStackTrace();
}
return System.nanoTime() - startTime;
}
Does anyone know of a way to give each thread the iterator, or create a class that shows all of the outer class members, particularly the CountDownLatches?
Just assign value of i to a final variable inside the loop.
for (int i = 1; i <= cores; i++){
final int iFinal = i;
exec.execute(new Runnable(){
public void run(){
ready.countDown();
try{
start.await();
System.out.println( "i=" + iFinal );
} catch (InterruptedException e){
Thread.currentThread().interrupt();
} finally{
done.countDown();
exec.shutdown();
}
}
});
}
If I understand correctly you want the runnable to keep a "reference" to the iterator so that it can observe the increments. One way to do it which is thread safe is to use an AtomicInteger:
final AtomicInteger i = new AtomicInteger(1);
for (; i.get() <= cores; i.incrementAndGet()){
exec.execute(new Runnable(){
public void run(){
//you can access i here
int j = i.get();
}
});
}
Note that this assumes that you only read i from the Runnables - if you also write it, the behaviour of the condition i.get() <= cores could be unexpected.
You can use this trick:
final int[] holder = new int[1]; // the array is final, not its contents
for (int i = 1; i <= cores; i++){
holder[0] = i;
exec.execute(new Runnable(){
public void run(){
int i = holder[0]; // compiles
ready.countDown();
try{
start.await();
//do work
}
} catch (InterruptedException e){
Thread.currentThread().interrupt();
} finally{
done.countDown();
exec.shutdown();
}
}
});
}
The reason this compiles is that the array reference is final, but the contents of the array is able to be changed.
I'm not sure how useful this will be, because although I didn't read your code thoroughly, it doesn't seem threadsafe - the order of execution of threads is indeterminable, so your iterated value could be anything when the Runnable actually executes.
This kind of goes against your question but another solution is to work with some of Java's functional programming libraries. I hate writing threads and these libraries let you simply write out the problem you're attempting to solve with higher-order logic and handles concurrency optimization behind the scenes.
Guava and lambdaJ are easy to work with.
what I need to do is be able to stop all threads running from one thread class that implements runnable. This is what I mean: here is the beginning of my "thread" class:
public class HTTP extends Thread
{
int threadNumber;
String host;
int port;
int timeLeft;
private BufferedReader LocalBufferedReader;
public HTTP(int threadNumber, String host, int port, int timeLeft)
{
this.threadNumber = threadNumber;
this.host= host;
this.port = port;
this.timeLeft = (timeLeft * 1000);
}
public void run()
{
This is how I am creating the multiple threads to do this:
for (int n = 1; n <= m; n++) {
new HTTP(n + 1, str, j, k).start();
}
m is the number of threads to create. This can be anywhere from 50-1000. Now what I need to do is just abruptly stop all of them at once. How can I do that?
First store all the threads:
ArrayList<Thread> threads = new ArrayList<Thread>();
for (int n = 1; n <= m; n++) {
Thread t = new HTTP(n + 1, str, j, k);
threads.add(t);
t.start();
}
Now for stop method, just loop all the threads and call interrupt on them:
for(Thread thread : threads)
{
thread.interrupt();
}
Make sure to check isIntruppted() in your HTTP threads. So you would do something like this:
public class InterruptTest {
static class TThread extends Thread {
public void run() {
while(!isInterrupted()) {
System.out.println("Do Work!!!");
try {
sleep(1000);
} catch (InterruptedException e) {
return;
}
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread t = new TThread();
t.start();
Thread.sleep(4000);
System.out.println("Sending interrupt!!");
t.interrupt();
Thread.sleep(4000);
}
}
Stopping threads in Java is a cooperative process implemented with interruptions. You could store your threads and interrupt them one by one:
List<Thread> threads = new ArrayList<> ();
for (int n = 1; n <= m; n++) {
Thread t = new HTTP(n + 1, str, j, k);
threads.add(t);
t.start();
}
//later on
for (Thread t : threads) {
t.interrupt();
}
However, it is worth noting a few things:
this will only work if your run method reacts to interruption by stopping what it is doing
you could do the same thing more easily with a thread pool, for example by using one of the ExecutorService returned by the various factory methods provided by the Executors class. They would indeed handle the lifecycle of threads for you.
Firstly, starting 1000 threads is practically pointless as few of them will be scheduled to actually run concurrently.
Secondly, you can't "stop" threads. All you can do is ask them nicely via cooperative code to stop.
The easiest way to do what you want is to shutdown the JVM.
I have a thread with the following form:
each execution of each thread is supposed to run a function in the class. That function is completely safe to run by itself. The function returns a value, say an int.
After all threads have been executed, the function values need to be accumulated.
So, it goes (in pseudo-code) something like that:
a = 0
for each i between 1 to N
spawn a thread independently and call the command v = f(i)
when thread finishes, do safely: a = a + v
end
I am not sure how to use Java in that case.
The problem is not creating the thread, I know this can be done using
new Thread() {
public void run() {
...
}
}
the problem is accumulating all the answers.
Thanks for any info.
I would probably do something like:
public class Main {
int a = 0;
int[] values;
int[] results;
public Main() {
// Init values array
results = new int[N];
}
public int doStuff() {
LinkedList<Thread> threads = new LinkedList<Thread>();
for (final int i : values) {
Thread t = new Thread() {
public void run() {
accumulate(foo(i));
}
};
threads.add(t);
t.start();
}
for (Thread t : threads) {
try {
t.join();
} catch (InterruptedException e) {
// Act accordingly, maybe ignore?
}
}
return a;
}
synchronized void accumulate(int v) {
// Synchronized because a += v is actually
// tmp = a + v;
// a = tmp;
// which can cause a race condition AFAIK
a += v;
}
}
Use an ExecutorCompletionService, Executor, and Callable.:
Start with a Callable that calls your int function:
public class MyCallable implements Callable<Integer> {
private final int i;
public MyCallable(int i) {
this.i = i;
}
public Integer call() {
return Integer.valueOf(myFunction(i));
}
}
Create an Executor:
private final Executor executor = Executors.newFixedThreadPool(10);
10 is the maximum number of threads to execute at once.
Then wrap it in an ExecutorCompletionService and submit your jobs:
CompletionService<Integer> compService = new ExecutionCompletionService<Integer>(executor);
// Make sure to track the number of jobs you submit
int jobCount;
for (int i = 0; i < n; i++) {
compService.submit(new MyCallable(i));
jobCount++;
}
// Get the results
int a = 0;
for (int i = 0; i < jobCount; i++) {
a += compService.take().get().intValue();
}
ExecutorCompletionService allows you to pull tasks off of a queue as they complete. This is a little different from joining threads. Although the overall outcome is the same, if you want to update a UI as the threads complete, you won't know what order the threads are going to complete using a join. That last for loop could be like this:
for (int i = 0; i < jobCount; i++) {
a += compService.take().get().intValue();
updateUi(a);
}
And this will update the UI as tasks complete. Using a Thread.join won't necessarily do this since you'll be getting the results in the order that you call the joins, not the order that the threads complete.
Through the use of the executor, this will also allow you to limit the number of simultaneous jobs you're running at a given time so you don't accidentally thread-bomb your system.