I thought I might be able to do it by trying something like this, but it doesn't work:
Thread[] threads = new Thread[myNumThreads];
for (int i=0; i<myNumThreads; i++) {
threads[i] = new Thread () {
#Override
public void run() {
<Code to do when running>
}
//CODE I TRIED TO ADD:
public boolean getValue(){
return true;
}
};
}
Basically instead of calling join() to end a thread I want a way to get a thread to do something and return some data to the main method while still running.
When you run code, it always uses the current thread. If the code is attached to another thread object, e.g. Thread.join(); it is still the current thread which waits while the background thread runs.
The simplest way to get another thread to do work is to use an ExecutorService
ExecutorService es = Executors.newFixedThreadPool(myNumThreads);
List<Future<ResultType>> futures = new ArrayList<>();
for (int i = 0; i < myNumThreads; i++) {
futures.add(es.submit(new Callable<Result>() {
public ResultType call() {
// do something
return result;
}
});
}
// do something while the thread task executes
for (Future<ResultType> future: futures) {
ResultType result = future.get();
}
// when finished with the pool
es.shutdown();
Its hard to figure out what you mean by "it doesn't work" but I think you might just missing a call to
threads[i].start();
If however you want to be able to call the getValue() method from outside of the class then you will need to create a new MyThread class which extends Thread and use that type instead of thread:
class MyThread extends Thread {
#Override
public void run() {
for (int j=0 ; j< 10; j++) {
System.out.println("working:" + j + ":" + this.getValue());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//CODE I TRIED TO ADD:
public boolean getValue(){
return true;
}
}
And then call it as follows:
int myNumThreads = 10;
MyThread[] threads = new MyThread[myNumThreads];
for (int i=0; i<myNumThreads; i++) {
threads[i] = new MyThread () ;
threads[i].start();
}
System.out.println(threads[0].getValue());
You can try to write your own Thread: Like "MyThread extends Thread"
Related
I'm trying to spin up many threads in a Producer-Consumer model in Java and for some reason it's not doing what it's supposed to.
I have code that does
List<Thread> consumers = new ArrayList<>();
for (int i = 0; i < noOfThreads; i++) {
Thread consumer = new Thread(new Runnable() {
String name = "Thread-" + UUID.randomUUID();
#Override
public void run() {
try {
pc.consume(name);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
consumers.add(consumer);
consumer.start();
consumer.join();
}
where pc is a ProducerConsumer whose consume method is
public void consume(String name) throws InterruptedException {
while (true) {
synchronized (this) {
while (subQueue.size() == 0) {
wait(2000);
}
Subscriber sub = subQueue.poll();
System.out.println(name);
uploadEndpointToPinpoint(sub);
notify();
}
}
}
So, when I run this I expect to see it print out 10 different UUIDs, indicating that there are 10 threads running - but that's not happening. Instead I just get:
Thread-c42ac697-d4ad-4944-a20e-907952f5d5ab
Thread-c42ac697-d4ad-4944-a20e-907952f5d5ab
Thread-c42ac697-d4ad-4944-a20e-907952f5d5ab
Thread-c42ac697-d4ad-4944-a20e-907952f5d5ab
Thread-c42ac697-d4ad-4944-a20e-907952f5d5ab
Thread-c42ac697-d4ad-4944-a20e-907952f5d5ab
Thread-c42ac697-d4ad-4944-a20e-907952f5d5ab
which means that it only started one of the threads. Why is the for loop not doing what I think it should?
Any and all help would be appreciated.
Calling Thread#join() blocks the current thread until the target thread is not running anymore. In your loop you're essentially starting a single thread and then waiting for it to complete, which is why you only see one thread. If you want to wait for all the threads to complete you need to move the join() call outside the loop that creates the thread.
List<Thread> consumers = new ArrayList<>();
for (int i = 0; i < noOfThreads; i++) {
Thread consumer = new Thread(new Runnable() {
String name = "Thread-" + UUID.randomUUID();
#Override
public void run() {
try {
pc.consume(name);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
consumers.add(consumer);
consumer.start();
}
for (Thread thread : consumers) {
thread.join();
}
Threads are stored in an ArrayList so that they can dynamically be set later on by their name. There are a lot of examples on the Internet, all about this, but I do not work, so the selected thread does not stop.
What can my fault be?
public class Szal {
static ArrayList<MyThread> myThread;
static String[] names;
public Szal() {
myThread = new ArrayList<MyThread>();
names = new String[]{"EZ", "AZ"};
for (int i = 0; i < names.length; i++) {
MyThread t = new MyThread(names[i]);
myThread.add(t);
t.start();
}
}
public static void main(String[] args) {
new Szal();
Thread[] thread = new Thread [Thread.activeCount ()];
int m = Thread.enumerate (thread);
for (int i = 0; i < m; i++) {
System.out.println (thread[i].getName());
}
// Why is this not working?
for (Thread t : myThread) {
if (t.getName().equalsIgnoreCase("EZ")) {
t = Thread.currentThread();
t.interrupt();
myThread.remove(t);
}
}
Thread[] threads = new Thread [Thread.activeCount ()];
int c = Thread.enumerate (threads);
for (int i = 0; i < c; i++) {
System.out.println (threads[i].getName());
}
}
class MyThread extends Thread {
public MyThread(String name) {
super(name);
}
public void run() {
while (true) {
}
}
}
}
//this why not working???
for(Thread t : myThread){
if(t.getName().equalsIgnoreCase("EZ")){
t= Thread.currentThread();
t.interrupt();
myThread.remove(t);
}
}
You iterate over all threads in the list and iterrupt yourself as soon as you reach the one with the name EZ. I'm not sure if that's what you actually planned to do, your question sounded more like you wanted to interrupt the EZ-Thread. In that case you should omit the line t = Thread.currentThread().
You haven't explained what exactly you mean with "not working", I assume that you mean that the thread you interrupted still continues to run. That's because, none of the threads is actually performing an operation that is checking the fact if it's interrupted.
You might change your MyThread-implementation this way:
class MyThread extends Thread{
public MyThread(String name) {
super(name);
}
public void run() {
try {
while(true){
Thread.sleep(10);
}
}
catch(InterrutedException ie) {
// leads to the end of the thread
}
}
}
or alternatively
while(!interrupted()){
}
Oh, and wait a bit between interrupting and outputting all Threads. Starting and shutting down threads is a complex task that takes some time. So even with fully functional code that reliably shuts down your Thread, the interrupted one might still show up as active if you list all threads immediately afterwards.
package threadShareResource1;
public class NonSynchro1 {
private int sum = 0;
public static void main(String[] args) {
NonSynchro1 n = new NonSynchro1();
n.task();
System.out.println(n.getSum());
}
public synchronized void sumAddOne(){
sum++;
}
public void task(){
for (int i = 0; i < 100; i++) {
new Thread(new Runnable(){
#Override
public void run() {
sumAddOne();
}
}).start();
/* try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
} */
}
}
public int getSum() {
return sum;
}
}
Without the commented part of code, the program has data corruption, which is not 100 every time I run it. But I thought the synchronized keyword should acquires a lock on the sumAddOne method, which is the critical region of my program, allowing one thread accessing this method every time.
I've try to use ExecutorService as well, but it doesn't give 100 all the runs.
public void task(){
ExecutorService s = Executors.newCachedThreadPool();
for (int i = 0; i < 100; i++) {
s.execute(new Thread(new Runnable(){
#Override
public void run() {
sumAddOne();
}
}));
}
s.shutdown();
while(!s.isTerminated()){}
}
In Task(), you start 100 threads (which is a lot) and each one is to add 1 to sum.
But when Task is done all you know is that 100 threads are in some process of having started. You don't block before calling println(), so how do you know all the threads have completed?
The sleep probably "prevents the corruption" just because it gives the system time to finish launching all the threads.
Beyond that you are using Synchronized correctly. Any place multiple threads may write to the same variable you need it and, in general (simplifying), you don't need it if you are only reading.
Synchronised keyword is used correctly, the problem is that you are not waiting for the threads to finish. Here is a possible solution:
public class NonSynchro1 {
private static final ExecutorService executorService = Executors.newCachedThreadPool();
private int sum = 0;
public static void main(String[] args) {
NonSynchro1 n = new NonSynchro1();
n.task();
System.out.println(n.getSum());
executorService.shutdown();
}
public synchronized void sumAddOne() {
sum++;
}
public void task() {
List<Callable<Object>> callables = new ArrayList<>();
for (int i = 0; i < 100; i++) {
callables.add(() -> {
sumAddOne();
return null;
});
}
List<Future<Object>> futures;
try {
futures = executorService.invokeAll(callables);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
futures.forEach(future -> {
try {
future.get();
} catch (ExecutionException | InterruptedException e) {
throw new RuntimeException(e);
}
});
}
public int getSum() {
return sum;
}
}
First we create a list of callables - a list of functions that will be executed in parallel.
Then we invoke them on the executor service. newCachedThreadPool I have used here, by default has 0 threads, it will create as many as necessary to execute all passed callables, the threads will be killed after being idle for a minute.
Finally, in the for-each loop we resolve all futures. get() call will block until the function was executed by the executor service. It will also throw exception if it was thrown inside the function (without calling get() you would not see such exception at all).
Also, it is a good idea to shutdown the executor service when you want to terminate the program gracefully. In this case, it is just executorService.shutdown() at the end of main method. If you don't do this, the program will terminate after a minute when idle threads are killed. However, if different executor service, threads might not be killed when idle, in which case the program would never terminate.
Just for completeness sake: Here's a solution showing how the original program can be made to wait for all threads to finish by joining them:
for (Thread t : n.task())
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
which requires task to return the threads it creates. In this case we don't need to complicate things with caching managers or collections: a simple array will do. Here's the complete class:
public class TestSynchro1 {
private int sum = 0;
public synchronized void sumAddOne() {
sum++;
}
public Thread[] task(int n) {
Thread[] threads = new Thread[n];
for (int i = 0; i < n; i++) {
(threads[i] = new Thread(new Runnable() {
#Override
public void run() {
sumAddOne();
}
})).start();
}
return threads;
}
public static void main(String[] args) {
TestSynchro1 n = new TestSynchro1();
for (Thread t : n.task(100))
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(n.sum);
}
}
In Java you can use Thread.join() to wait for a thread to exit
Is there a similar method that will allow you to wait for any thread in a list of threads to exit?
This would be similar to the wait(2) Unix system call that returns when any child process exits.
You could use a CountDownLatch from the java.util.concurrent package. Something like this:
CountDownLatch c = new CountDownLatch(3);
...
c.await();
Look at CountDownLatch if you are using Java 1.5 or above
Suppose you need to submit a set of background tasks, and you want to wait for each one to become available and process its result, but you don't want to block waiting for all of them before you start processing. You can use an ExecutorCompletionService.
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
public final class Main {
public static void main(String[] args) throws Exception {
// Bootstrap CompletionService backed by a pool of 5 daemon threads.
CompletionService<Integer> cs = new ExecutorCompletionService<Integer>(
Executors.newFixedThreadPool(5, new ThreadFactory() {
#Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
}
}));
// Submit 20 contrived Callables that just return a monotonically
// increasing integer. Introduce a random sleep just to make the
// multi-threading effects more visible.
int n = 20;
for (int i = 0; i < n; ++i) {
final Integer result = i;
// The submit call does not block here.
cs.submit(new Callable<Integer>() {
#Override
public Integer call() {
try {
Thread.sleep((long)(Math.random() * 10));
return result;
} catch (InterruptedException e) {
return null;
}
}
});
}
for (int i = 0; i < n; ++i) {
// The take call blocks here until the next Callable finishes.
Integer result = cs.take().get();
if (result != null) {
System.out.println(result);
}
}
}
}
CountdownLatch is nice, but a Semaphore is re-useable.
final Semaphore semaphore = new Semaphore(0);
class WaitedForTask implements Runnable {
#Override
public void run() {
try {
doSomethingUseful();
} finally {
semaphore.release();
}
}
}
void runnem() throws InterruptedException {
Thread[] thread = new Thread[NUMTHREADS];
for (int i=0 ; i<NUMTHREADS ; i++) {
thread[i] = new Thread(new WaitedForTask());
thread[i].start();
}
for (int i=0 ; i<NUMTHREADS ; i++) {
semaphore.acquire();
System.out.println("Another one bites the dust.");
}
}
I am newb to java execuatorservice.
i went threw some examples in internet but i have some basic doubt.
i created a callable class like below
public class ReadTest implements Callable<String> {
#Override
public String call() throws Exception {
return "OK";
}
}
and i created my main class like below
public class ThreadMain {
public static void main(String args[]) {
try {
ExecutorService execuator = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
Future<String> future;
System.out.println("I : " + i);
future = execuator.submit(new ReadTest());
System.out.println(future.get());
future.cancel(true);
}
execuator.shutdownNow();
} catch (Exception ex) {
System.out.println("Error : " + ex);
}
}
}
i am creating FixedThreadPool with limit 5. my loop is running up to 10 times.
1. Here how many threads will be created and used.(according to my view only one thread used, because i cancel with future object every time. is it correct?)
2.i want to execute multiple tasks like above for loop. i have list of commands to execute in shell using jsch. how to do this with threads ?
any help will be appreciated
Are you trying to run async tasks, must do something else while waiting? Maybe this is not what you are looking for but you were studying java executorservice. This app uses async concurrent threads what you were looking for?
public class ThreadMain {
public static void main(String args[]) {
try {
// start async(threaded) workers
ExecutorService execuator = Executors.newFixedThreadPool(5);
List<Future<String>> workers = new ArrayList<Future<String>>();
for (int idx=0; idx < 10; idx++)
workers.add( execuator.submit(new ReadTest()) );
// loop until all workers is done, results may arrive in random order,
// if none is ready then do something else while waiting for next result.
while(!workers.isEmpty()) {
Future<String> worker=null;
for(int idx=0; idx < workers.size(); idx++) {
worker = workers.get(idx);
if (worker.isDone()) {
worker.remove(idx);
break;
}
worker = null;
}
if (worker==null) {
Thread.sleep(500); // do something else, like idle
} else {
System.out.println("Worker is done with results " + worker.get() );
}
}
execuator.shutdown();
} catch (Exception ex) {
System.out.println("Error : " + ex);
}
}
}