public class SieveGenerator{
static int N = 50;
public static void main(String args[]){
int cores = Runtime.getRuntime().availableProcessors();
int f[] = new int[N];
//fill array with 0,1,2...f.length
for(int j=0;j<f.length;j++){
f[j]=j;
}
f[0]=0;f[1]=0;//eliminate these cases
int p=2;
removeNonPrime []t = new removeNonPrime[cores];
for(int i = 0; i < cores; i++){
t[i] = new removeNonPrime(f,p);
}
while(p <= (int)(Math.sqrt(N))){
t[p%cores].start();//problem here because you cannot start a thread which has already started(IllegalThreadStateException)
try{
t[p%cores].join();
}catch(Exception e){}
//get the next prime
p++;
while(p<=(int)(Math.sqrt(N))&&f[p]==0)p++;
}
//count primes
int total = 0;
System.out.println();
for(int j=0; j<f.length;j++){
if(f[j]!=0){
total++;
}
}
System.out.printf("Number of primes up to %d = %d",f.length,total);
}
}
class removeNonPrime extends Thread{
int k;
int arr[];
public removeNonPrime(int arr[], int k){
this.arr = arr;
this.k = k;
}
public void run(){
int j = k*k;
while(j<arr.length){
if(arr[j]%k == 0)arr[j]=0;
j=j+arr[k];
}
}
}
Hi I'm getting an IllegalThreadStateException when I run my code and I've figured it's because I am trying to start a thread that has already been started. So how could I kill
or stop the thread each time, to get around this problem?
how could I kill or stop the thread each time, to get around this problem?
The answer is, you can't. Once started, a Thread may not be restarted. This is clearly documented in the javadoc for Thread. Instead, what you really want to do is new an instance of RemoveNonPrime each time you come around in your loop.
You have a few other problems in your code.
First, you need to increment p before using it again:
for(int i = 0; i < cores; i++){
t[i] = new removeNonPrime(f,p); //<--- BUG, always using p=2 means only multiples of 2 are cleared
}
Second, you might be multithreaded, but you aren't concurrent. The code you have basically only allows one thread to run at a time:
while(p <= (int)(Math.sqrt(N))){
t[p%cores].start();//
try{
t[p%cores].join(); //<--- BUG, only the thread which was just started can be running now
}catch(Exception e){}
//get the next prime
p++;
while(p<=(int)(Math.sqrt(N))&&f[p]==0)p++;
}
Just my $0.02, but what you are trying to do might work, but the logic for selecting the next smallest prime will not always pick a prime, for example if one of the other threads hasn't processed that part of the array yet.
Here is an approach using an ExecutorService, there are some blanks (...) that you will have to fill in:
/* A queue to trick the executor into blocking until a Thread is available when offer is called */
public class SpecialSyncQueue<E> extends SynchronousQueue<E> {
#Override
public boolean offer(E e) {
try {
put(e);
return true;
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
return false;
}
}
}
ExecutorService executor = new ThreadPoolExecutor(cores, cores, new SpecialSyncQueue(), ...);
void pruneNonPrimes() {
//...
while(p <= (int)(Math.sqrt(N))) {
executor.execute(new RemoveNonPrime(f, p));
//get the next prime
p++;
while(p<=(int)(Math.sqrt(N))&&f[p]==0)p++;
}
//count primes
int total = 0;
System.out.println();
for(int j=0; j<f.length;j++){
if(f[j]!=0){
total++;
}
}
System.out.printf("Number of primes up to %d = %d",f.length,total);
}
class RemoveNonPrime extends Runnable {
int k;
int arr[];
public RemoveNonPrime(int arr[], int k){
this.arr = arr;
this.k = k;
}
public void run(){
int j = k*k;
while(j<arr.length){
if(arr[j]%k == 0)arr[j]=0;
j+=k;
}
}
}
You could implement Runnable instead and use new Thread( $Runnable here ).start() or use a ExecutorService to reuse threads.
* It is never legal to start a thread more than once.
* In particular, a thread may not be restarted once it has completed
* execution.
*
* #exception IllegalThreadStateException if the thread was already started
*/
public synchronized void start() {
In Android, document still mention that we will get IllegalThreadStateException if the thread was already started.
However for some device it will not throw this exception (tested on Kyocera 7.0). In some popular device like Samsung, HTC, it throw throw the exception normally
I answer here because the Android question is mark as duplicated to this question.
Why does an IllegalThreadStateException occur when Thread.start is
called again
Because JDK/JVM implementers coded Thread.start() method that way. Its a reasonable functional expectation to be able to restart a thread after a thread has completed its execution and that is what being suggested in chrisbunney's answer ( and I have put in a comment in that answer ) but if you look at Thread.start() implementation , the very first line is ,
if (threadStatus != 0)
throw new IllegalThreadStateException();
where threadStatus == 0 means NEW state so my guess is that implementation doesn't resets this state to zero after execution has completed & thread is left in TERMINATED state ( non - zero state ). So when you create a new Thread instance on same Runnable , you basically reset this state to zero.
Also, I noticed the usage of word - may & never in same paragraph as different behavior is being pointed out by Phan Van Linh on some OSes,
It is never legal to start a thread more than once. In particular, a
thread may not be restarted once it has completed execution.
I guess what they are trying to say in above Javadoc that even if you don't get IllegalThreadStateException on certain OS, its not legal in Java/Thread class way & you might get unexpected behavior.
The famous thread state diagrams depict the same scenario - no going back from dead state to new.
ThreadPools can be used for delivering tasks to set number of threads. When initiating you set the number of threads. Then you add tasks for the pool. And after you can block until all tasks have finished processing. Here is some sample code.
I am not at all sure I understand the question. All the methods for stopping threads that are executed from other threads are deprecated; the way to stop a thread is to have it check a variable that it and another thread can access (perhaps a volatile variable), and have the running thread check it occasionally to see if it should exit on its own.
I cannot tell why/whether you want to eliminate the running thread and use another one, and I cannot see how the different threads are going to help execute your overall goal any faster. But it's possible I'm just not understanding the math.
The Thread.isAlive() method can tell you if the Thread has already been started. Simply do this where you want to start your thread:
if(!t[p%cores].isAlive()){
t[p%cores].start();
}
Related
I have an array of threads and I want to start a few of them. The point is that I want to stop the threads with in a for loop.
In the for loop I want to check all threads if they are running or not, and if they are, I want to be asked if I want stop them(dialog box yes/no).
The problem is that the loop doesn't display all the times all three dialog boxes for all those three started thread. Sometime appear 1 dialog box, sometime 3 dialog boxes etc.
So, I do not have the chance to stop all three threads...
public class Main {
public static void main( String[] args )
{
Counter[] arrayOfThreads = new Counter[10];
for( int i = 0; i < arrayOfThreads.length; i++ )
{
arrayOfThreads[i] = new Counter( );
}
arrayOfThreads[3].start( );
arrayOfThreads[5].start( );
arrayOfThreads[2].start( );
for( int i = 0; i < arrayOfThreads.length; i++ )
{
if( arrayOfThreads[i].getState( ) == State.RUNNABLE )
{
int dialogButton = JOptionPane.YES_NO_OPTION;
int dialogResult = JOptionPane.showConfirmDialog( null, "Do you want to stop the theread: " + i, "Warning", dialogButton );
if( dialogResult == JOptionPane.YES_OPTION )
{
arrayOfThreads[i].stopProcessing( );
}
}
}
}
}
class Counter extends Thread
{
volatile boolean processing;
public void run( )
{
int i = 0;
processing = true;
while( processing )
{
System.out.println( " Number: " + i );
i++;
}
System.out.println( "finish" );
}
public void stopProcessing( )
{
processing = false;
}
}
EDIT:
So all what I want is when I press the EXIT button to close the threads and to dispose the frame if all the threads are stoped. I modified the first class to more more clear.
public class Program extends Frame {
public static void main(String[] args) {
Counter[] arrayOfThreads = new Counter[10];
for (int i = 0; i < arrayOfThreads.length; i++) {
arrayOfThreads[i] = new Counter();
}
Program program = new Program(arrayOfThreads);
program.startThreeThreads(1, 4, 5);
}
private Counter[] arrayOfThreads;
private JButton stopThreads;
public Program(Counter[] arrayOfThreads) {
this.arrayOfThreads = arrayOfThreads;
stopThreads = new JButton("STOP THREADS");
closeThreadsWhenExitIsPressed();
setSize(300, 200);
setLayout(new FlowLayout());
add(stopThreads);
setVisible(true);
}
public void closeThreadsWhenExitIsPressed() {
stopThreads.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
stopRunningThreadsMethod();
dispose();
}
});
}
private void startThreeThreads(int first, int second, int third) {
for (int i = 0; i < arrayOfThreads.length; i++) {
if (i == first || i == second || i == third) {
arrayOfThreads[i].start();
continue;
}
}
}
public void stopRunningThreadsMethod() {
for (int i = 0; i < arrayOfThreads.length; i++) {
if (arrayOfThreads[i].isAlive()) {
int dialogButton = JOptionPane.YES_NO_OPTION;
int dialogResult = JOptionPane.showConfirmDialog(null, "Do you want to stop the theread: " + i,
"Warning", dialogButton);
if (dialogResult == JOptionPane.YES_OPTION) {
arrayOfThreads[i].stopProcessing();
}
}
}
}
}
The documentation for getState() is (my emphasis):
Returns the state of this thread. This method is designed for use in
monitoring of the system state, not for synchronization control.
You're trying to use it for synchronization so you're already outside recommendation.
If you look at Thread.State you'll see it isn't always RUNNABLE and I suspect, as is common, System.out is synchronized so although not obvious from your code the thread could be WAITING (on another competing thread to use System.out).
Given all your thread does is hammer output it's probably quite common one or more is waiting. You could even find none show the dialog because as you go round the loop you happen to coincide with that thread waiting!
Check this by reading the state and outputting it!
So first, don't use getState() for synchronization and be aware you don't always know what synchronization is going on 'behind the scenes' in libraries you're using.
The documentation gives leave for the implementer to maybe cut corners in low-level synchronization of getState() and the value may not be 'first class' reliable (synchronized), but regardless don't do things you're told not to even if you don't know why!
The right method is isAlive(). The thread is alive if it has had its start() method called and not yet terminated. Waiting or not, it's alive...
Next problem, is because you set processing=true; in the run() method you could call stopProcessing() before processing has been set true.
There is no guarantee how far (if anywhere) down run() the thread has got when you reach stopProcessing() in the main thread.
I know there's a user interaction (e.g. big delay) but on an overloaded (or single threaded!) machine or a future use case it is possible for processing=true; to be executed after stopProcessing() sets it false. That may lead to 'runaway' processing.
So use volatile boolean processing=true; in the class declaration or set it in the constructor. That guarantees it will be set by the end of the constructor (takes place in the controlling thread) and must be before stopProcessing() is called.
Your application is (of course) a toy but think about when you would stop the threads the user didn't stop.
It's bad practice to just end the JVM without bringing all threads to a safe conclusion.
That doesn't matter in your toy but in real applications you may want to release external resources and (say) flush file buffers rather than let the JVM pull the run out.
That is, finally call stopProcessing() on all the threads in one loop and then join() in a second loop before ending the application.
It's important to use two loops because it makes sure the threads are all stopping concurrently and not one after the other.
I can't emphasise enough why you should end threads properly. People often ignore me and then long into to development have weird glitches that difficult to localise and hard to drive out.
Other considerations:
Consider using interrupt(). It's designed to help terminate threads and does nice things for you like jump them out of sleep and wait conditions (with an Interrupted exception). That will mean they may terminate faster (never slower) than your approach.
Again, not relevant in a toy but valuable in serious application.
Consider sub-classing Runnable instead of Thread. Again your toy is fine and valid but again 'real' applications end up preferring Runnable and using a thread pool of some kind (e.g. ExecutorService). That's clever because on many platforms the overhead of creating and destroying Threads is far larger than a lighter-weight Runnable.
That's the standard advice but I don't think its wisdom is always explained.
The threads probably haven't started by the time you enter the loop in main. Their states are Thread.State.NEW when you check arrayOfThreads[i].getState().
A simple solution would be either to wait some time before executing the loop to make sure the threads are running or to run a while loop over your loop to check the condition more than once.
Both are spotty and inefficient because you don't know exactly when the thread will be up and running. Instead, I would advise implementing a wait-notify mechanism to show a dialogue when the thread is certainly running.
This question already has answers here:
Why is i++ not atomic?
(10 answers)
What is a debugger and how can it help me diagnose problems?
(2 answers)
Closed 4 years ago.
I wanted to test out multithreading for a project of mine, trying to also develop a solution in case something goes wrong.
So I made this small test:
main
public class main
{
static int addToCounter;
static int addToErrorCounter;
public static void main(String[] args) throws InterruptedException
{
int threads = 10;
Executor exec = new Executor();
for (int i = 0; i < threads; i++)
{
double error = Math.random();
testClass aldo = new testClass();
Thread thread = aldo.getThread(300, error);
exec.execute(thread);
}
while (threads != (addToCounter + addToErrorCounter))
{
System.out.println("Not all threads finished, number of finished threads is: " + (addToCounter + addToErrorCounter));
Thread.sleep(50);
}
System.out.println("Number of Threads that finished correctly: " + addToCounter);
}
}
testClass
import test1.main;
public class testClass
{
public Thread getThread(long time, double error)
{
Thread thread = new Thread()
{
public void run()
{
try
{
Thread.sleep(time);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
if (error > 0.5)
{
main.addToErrorCounter++;
throw new java.lang.Error("HELLO");
}
System.out.println("I DID THIS!");
main.addToCounter++;
}
};
return thread;
}
}
(you'll have to fix the imports, also I use a custom class Executor, although that's only a wrapper for ExecutorService)
The weird behaviour is that sometimes it works properly, and sometimes it doesn't (total terminated thread count is 9, although I can see clearly it printed "I DID THIS!" and the error exactly 10 times).
Any fix?
The Problem might be a racecondition.
the "++" operator is not atomic.
Imageine the following scenario. There are two Threads at the same time. both want to increase a number and finish.
The initial value of the number is 0.
Thread 0 reads the number, knows now it is 0.
Thread 1 reads the number, knows now it is 0.
Thread 0 (who knew it was 0) now writes 1 to the memory.
Thread 1 does not know, that the number has changed, and still believes the number is 0 so he also writes a 1 to the memory.
You need something like a synchronizing mechanisim, something like a lock, or a semaphore or something else.
have a look at this for more information: http://winterbe.com/posts/2015/04/30/java8-concurrency-tutorial-synchronized-locks-examples/
for your example you could use the "synchronized" example from that link.
add a method to your main class looking like this to increment the addToCounter and also to the addToErrorCounterto remove the effects from your error counter:
synchronized AddToError(int e){
addToError += e;
}
synchronized IncCounter(){
addToCounter++;
}
call those methods in your threads in the testclass instead of incrementing them unsynchronized.
My guess is that the postfix operator (main.addToCounter++) is not atomic. This line of code is probably equivalent to something like:
int temp = main.addToCounter;
main.addToCounter = temp + 1;
return temp;
With multiple threads doin this at the same time, two threads could obtain the same value for temp (because both peform the first line in the above pseudo-code before either performs the second), and hence the counter total will be too small once all threads are complete. See Why is i++ not atomic? for more information.
A quick fix in this situation is to make addToCounter an AtomicInteger, then use addToCounter.incrementAndGet() in place of addToCounter++.
I've got a little bit of work that is easily parallelizable, and I want to use Java threads to split up the work across my four core machine. It's a genetic algorithm applied to the traveling salesman problem. It doesn't sound easily parallelizable, but the first loop is very easily so. The second part where I talk about the actual evolution may or may not be, but I want to know if I'm getting slow down because of the way I'm implementing threading, or if its the algorithm itself.
Also, if anyone has better ideas on how I should be implementing what I'm trying to do, that would be very much appreciated.
In main(), I have this:
final ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(numThreads*numIter);
ThreadPoolExecutor tpool = new ThreadPoolExecutor(numThreads, numThreads, 10, TimeUnit.SECONDS, queue);
barrier = new CyclicBarrier(numThreads);
k.init(tpool);
I have a loop that is done inside of init() and looks like this:
for (int i = 0; i < numCities; i++) {
x[i] = rand.nextInt(width);
y[i] = rand.nextInt(height);
}
That I changed to this:
int errorCities = 0, stepCities = 0;
stepCities = numCities/numThreads;
errorCities = numCities - stepCities*numThreads;
// Split up work, assign to threads
for (int i = 1; i <= numThreads; i++) {
int startCities = (i-1)*stepCities;
int endCities = startCities + stepCities;
// This is a bit messy...
if(i <= numThreads) endCities += errorCities;
tpool.execute(new citySetupThread(startCities, endCities));
}
And here is citySetupThread() class:
public class citySetupThread implements Runnable {
int start, end;
public citySetupThread(int s, int e) {
start = s;
end = e;
}
public void run() {
for (int j = start; j < end; j++) {
x[j] = ThreadLocalRandom.current().nextInt(0, width);
y[j] = ThreadLocalRandom.current().nextInt(0, height);
}
try {
barrier.await();
} catch (InterruptedException ie) {
return;
} catch (BrokenBarrierException bbe) {
return;
}
}
}
The above code is run once in the program, so it was sort of a test case for my threading constructs (this is my first experience with Java threads). I implemented the same sort of thing in a real critical section, specifically the evolution part of the genetic algorithm, whose class is as follows:
public class evolveThread implements Runnable {
int start, end;
public evolveThread(int s, int e) {
start = s;
end = e;
}
public void run() {
// Get midpoint
int n = population.length/2, m;
for (m = start; m > end; m--) {
int i, j;
i = ThreadLocalRandom.current().nextInt(0, n);
do {
j = ThreadLocalRandom.current().nextInt(0, n);
} while(i == j);
population[m].crossover(population[i], population[j]);
population[m].mutate(numCities);
}
try {
barrier.await();
} catch (InterruptedException ie) {
return;
} catch (BrokenBarrierException bbe) {
return;
}
}
}
Which exists in a function evolve() that is called in init() like so:
for (int p = 0; p < numIter; p++) evolve(p, tpool);
Yes I know that's not terribly good design, but for other reasons I'm stuck with it. Inside of evolve is the relevant parts, shown here:
// Threaded inner loop
int startEvolve = popSize - 1,
endEvolve = (popSize - 1) - (popSize - 1)/numThreads;
// Split up work, assign to threads
for (int i = 0; i < numThreads; i++) {
endEvolve = (popSize - 1) - (popSize - 1)*(i + 1)/numThreads + 1;
tpool.execute(new evolveThread(startEvolve, endEvolve));
startEvolve = endEvolve;
}
// Wait for our comrades
try {
barrier.await();
} catch (InterruptedException ie) {
return;
} catch (BrokenBarrierException bbe) {
return;
}
population[1].crossover(population[0], population[1]);
population[1].mutate(numCities);
population[0].mutate(numCities);
// Pick out the strongest
Arrays.sort(population, population[0]);
current = population[0];
generation++;
What I really want to know is this:
What role does the "queue" have? Am I right to create a queue for as many jobs as I think will be executed for all threads in the pool? If the size isn't sufficiently large, I get RejectedExecutionException's. I just decided to do numThreads*numIterations because that's how many jobs there would be (for the actual evolution method that I mentioned earlier). It's weird though.. I shouldn't have to do this if the barrier.await()'s were working, which leads me to...
Am I using the barrier.await() correctly? Currently I have it in two places: inside the run() method for the Runnable object, and after the for loop that executes all the jobs. I would've thought only one would be required, but I get errors if I remove one or the other.
I'm suspicious of contention for the threads, as that is the only thing I can glean from the absurd slowdown (which does scale with the input parameters). I want to know if it is anything to do with how I'm implementing the thread pool and barriers. If not, then I'll have to look inside the crossover() and mutate() methods, I suppose.
First, I think you may have a bug with how you intended to use the CyclicBarrier. Currently you are initializing it with the number of executor threads as the number of parties. You have an additional party, however; the main thread. So I think you need to do:
barrier = new CyclicBarrier(numThreads + 1);
I think this should work, but personally I find it an odd use of the barrier.
When using a worker-queue thread-pool model I find it easier to use a Semaphore or Java's Future model.
For a semaphore:
class MyRunnable implements Runnable {
private final Semaphore sem;
public MyRunnable(Semaphore sem) {
this.sem = sem;
}
public void run() {
// do work
// signal complete
sem.release()
}
}
Then in your main thread:
Semaphore sem = new Semaphore(0);
for (int i = 0; i < numJobs; ++i) {
threadPool.execute(new MyRunnable(sem));
}
sem.acquire(numJobs);
Its really doing the same thing as the barrier, but I find it easier to think about the worker tasks "signaling" that they are done instead of "sync'ing up" with the main thread again.
For example, if you look at the example code in the CyclicBarrier JavaDoc the call to barrier.await() is inside the loop inside the worker. So it is really synching up the multiple long running worker threads and the main thread is not participating in the barrier. Calling barrier.await() at the end of the worker outside the loop is more signaling completion.
As you increase the number of tasks, you increase the overhead using each task adds. This means you want to minimise the number of tasks i.e. the same as the number of cpus you have. For some tasks using double the number of cpus can be better when the work load is not even.
BTW: You don't need a barrier in each task, you can wait for the future of each task to complete by calling get() on each one.
I'm trying to understand synchronization of multiple threads in Java more fully. I understand the high level idea behind the use of the synchronized keyword, and how it provides mutual exclusion among threads.
The only thing is that most of the examples I read online and in my textbook still work correctly even if you remove the synchronized keyword which is making this topic more confusing than I think it needs to be.
Can anyone provide me with a concrete example of when not including the synchronized keyword will produce erroneous results? Any information would be much appreciated.
You can usually trigger a race condition by increasing the number of iterations. Here's a simple example that works with 100 and 1,000 iterations but fails (at least on my quad-core box) at 10,000 iterations (sometimes).
public class Race
{
static final int ITERATIONS = 10000;
static int counter;
public static void main(String[] args) throws InterruptedException {
System.out.println("start");
Thread first = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < ITERATIONS; i++) {
counter++;
}
}
});
Thread second = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < ITERATIONS; i++) {
counter++;
}
}
});
first.start();
second.start();
first.join();
second.join();
System.out.println("Counter " + counter + " should be " + (2 * ITERATIONS));
}
}
>>> Counter 12325 should be 20000
This example fails because access to counter is not properly synchronized. It can fail in two ways, possibly both in the same run:
One thread fails to see that the other has incremented the counter because it doesn't see the new value.
One thread increments the counter between the other thread reading the current value and writing the new value. This is because the increment and decrement operators are not atomic.
The fix for this simple program would be to use an AtomicInteger. Using volatile isn't enough due to the problem with increment, but AtomicInteger provides atomic operations for increment, get-and-set, etc.
The thing about race conditions is that they don't necessarily happen if you don't do proper synchronization -- indeed, quite frequently it'll work just fine -- but then one year later, in the middle of the night, your code will crash with a completely unpredictable bug that you can't reproduce, because the bug only appears randomly.
Race conditions are so insidious precisely because they don't always make your program crash, and they trigger more or less randomly.
I'm writing a code that will run a multithreaded bank. I first create an array of threads with one program, then pass them into another thread that runs a loop to start them. For part of the application, I have a CPU intensive method that basically runs a series of loops within one another. Only problem is, for some reason it is not yielding the way that I think it should. Here is the code that is running the threads:
public void run(){
this.setPriority(MAX_PRIORITY);
int count = 0;
while(count<transactions.length){
int copy = count;
if(transactions[copy] instanceof Jumbler){
System.out.println(copy + " is a jumbler.");
}
else{
System.out.println(copy + " is not a jumbler");
}
transactions[copy].run();
count++;
}
}
Then here is the Jumbler run method:
public void run(){
System.out.println("running jumbler");
Thread.yield();
Thread.currentThread().yield();
try{
Thread.currentThread().sleep(5000);
}catch(InterruptedException e){}
//this.setPriority(MIN_PRIORITY);
System.out.println("still running.");
Thread.yield();
nums = new int[1000];
int i = 0;
do{
Thread.yield();
for(int x=0;x<1000;x++){
Thread.yield();
//System.out.println("in the loop");
nums[x]=(int)(Math.random()*10000)+1;
for(int y = 0;y<1000;y++){
Thread.yield();
//System.out.println("in the the loop");
for(int z = 0;z<100;z++){
Thread.yield();
}
}
}
Thread.yield();
i++;
System.out.println(whichJumble + ": " + i);
}while(i<1000);
}
So, the problem is that I want it to yield, allowing the main method to continue running more threads, but it blocks and waits for the Jumbler to complete (which takes a long time). Any idea why that would happen or how to fix it?
I suppose the issue comes with transactions[copy].run(); in your main loop. This one calls the run method directly but not in another system thread. Instead start the thread with transactions[copy].start();.
It seems that you're spawning the thread correctly (in fact, you're not spawning them at all)
If you want a Thread to start running (concurrently to the current thread) you need to call the start() method of that Thread object, which you don't.
If I understand your code correctly, you want the first snippet to spawn the other threads. Therefore you should change transactions[copy].run() to transactions[copy].start().
(This an educated guess. It would be nice if you showed the definition of the transaction array.)
Here's the typical scheme of launching several Threads:
class MyThread extends Thread {
public void run() {
// Do something here ...
}
}
// Prepare the array
MyThread[] arr = new MyThread[10];
for(int i = 0; i < arr.length; ++i)
arr[i] = new MyThread();
...
// Launch the threads
for(int i = 0; i < arr.length; ++i)
arr[i].start();
Once the thread is running, i don't think you can be guaranteed that priority changes when you call setPriority.
these two statements do the same thing:
Thread.yield();
Thread.currentThread().yield();
but you probably shouldn't be calling yield, let the os do that.