Java Thread Creates extra Threads I'm not sure why this happens! I'm still a noob at java if its very obvious I'm sorry but please help me out
Well I created 2 threads to do something but there are extra threads created
here's the code
import java.util.*;
import java.util.Arrays;
class consuming_producing extends Thread {
static int arrX[] = new int[300];
int y;
static int var=0;
int Request_type;
consuming_producing(int x, int Request) {
y = x;
Request_type = Request;
}
int thread_number;
consuming_producing(int x, int Request ,int thread) {
y = x;
thread_number=thread;
Request_type = Request;
}
public synchronized void run() {
switch (Request_type) {
case 1: {
// start producing the data and store it to the array
for (int i = y; i < 300; i = i + 3) {
arrX[i] = (int) (Math.random() * 10 + 1);
System.out.println("produced " + arrX[i]);
}
}
// *******************
case 2: { // consuming the data
for (int ww = y; ww < y+150;ww++) {
int sum = Arrays.stream(arrX).sum();
System.out.println("Sum =" +var+" by thread " + thread_number);
//Arrays.fill(arrX,0);
var+=1;
}
}
}
}
}
class consumer_producer {
public static void main(String[] args){
consuming_producing arr_Producer_obj[] = new consuming_producing[3];
// create a [enter image description here][1]thread for producing
for (int i=0;i<3;i++){
int x =0;
arr_Producer_obj[i]=new consuming_producing(x,1);
arr_Producer_obj[i].start();
x+=1;
}
// ***************
consuming_producing arr_Consumer_obj[]=new consuming_producing[2];
int thread=1; // this is the name of thread im creating for ny refrence
int x=0;
for (int i=0;i<=1;i++){
arr_Consumer_obj[i]=new consuming_producing(x,2, thread);
arr_Consumer_obj[i].start();
x+=150;
thread+=1;**
}
}
}
here's the image of output please check this
each time your program reaches a Thread.start() method, its creating a new thread, plus the base thread of the main() method/entry point.
Your main method has 2 for loops, the first looks like it would create 3 threads, and the 2nd looks like it would create 2 additional threads.
When you extend the Thread class, and implement the 'run()' method, calling start() on the instance of the class will create a new thread to run the 'run()' method on.
Well, your code has a lot of problems. But answer to your questions is simple:
You create a bunch of threads in 2 for loops, but there is no points of synchronization\ communication between threads, so they act independently in the meaning that when you call start method of a Thread instance it will execute run method, well, in separate thread. There is nothing in you program that prevents threads if 2nd loop to be created only after threads from 1st loop finish their execution. So there are no extra threads created here. You just solve your solution in a wrong way.
Related
I have started a Java coding short course at a university about 5 months ago. I have learnt quite the amount of things with regards to Java coding, but am still lacking in other things such as threads, handling exceptions, or even making JFrame games. I decided to embark on a text based game to just learn and figure out how a game loop should work (kind of), and how the logic should work (still, very "kind of"). The game I wrote runs with if-else commands, thus you get displayed a screen, type in the command of the option you want to pick, and it bumps you to the next menu, very standard of course. I run these if-else statements within nested for loops.
My nested for loops looks like the following:
// This is just an example, they're actually a lot more cluttered
// in my actual source code.
mainMenu.writeOutput();
reply = keyboardInput.nextLine();
for (int i = 0; i <= 10; i--)
{
for (int ii = 0; i <= 10; i--)
{
if (reply.equalsIgnoreCase("/help")
{
System.out.println("Here I have a separate call to a class
file (excuse me, forgot the exact wording), thus it
call something like help.writeOutput(); to display
the help menu");
reply = keyboardInput.nextLine();
if (reply.equalsIgnoreCase("/makegameeasy")
{
// Just an example.
gamedifficultyEasy.writeOutput();
reply = keyboardInput.nextLine();
if (reply.equalsIgnoreCase("/back")
{
mainMenu.writeOutput();
reply = keyboardInput.nextLine();
break;
}
}
else if (reply.equalsIgnoreCase("/makegamedifficult")
{
// Another example.
gamedifficultHard.writeOutput();
reply = keyboardInput.nextLine();
if (reply.equalsIgnoreCase("/back")
{
mainMenu.writeOutput();
reply = keyboardInput.nextLine();
break;
}
}
else if (reply.equalsIgnoreCase("/back")
{
mainMenu.writeOutput();
reply = keyboardInput.nextLine();
break;
}
}
else
{
System.out.println("Here I print out an error for incorrect
input received, standard fare.");
mainMenu.writeOutput();
reply = keyboard.nextLine();
break;
}
}
}
As mentioned, the above is just an example, it's not very elegant, and I can probably use Exceptions for any incorrect info submitted by the user, however I do not know too much of Exceptions to comfortably add them, so I'll do that at a later time, however my main issue at the moment is a part of my game where "resource mining" has to be done on regular intervals. I have been all over Google, but still can't quite catch how to set a Thread or Timer up for my game so it does the mining automatically, and the player can go on with their game.
The game is essentially one of those games where you build up a base, upgrade your mining tools, and generate more "stuff". I have pasted a few blocks of code from my "mining" class file below that will basically run how much of one thing should be mined. In the game you will be able to buy upgrades of course, so it will get factored into your mining speed.
// I initiate my variables a lot earlier, but just for some
// clarity, I have initiated the variables in the below methods,
// they will not work correctly anyway, I am aware of that, however
// I didn't want to add the other "get, set and initiate"
// variables and methods everywhere, as to not spam this block of code.
// upgradeOS, upgradeHF, and upgradeLM all have their own respective
// set and get methods. They are also all int variables.
public void handleOS()
{
// OS = short for Oxygen Silo
int mineOS = os.getStoredO2() + (1 * upgradeOS);
os.setStoredO2(mineOS);
}
public void handleHF()
{
// HF = short for Hydrogen Fuel
int mineHF = hf.getStoredO2() + (1 * upgradeHF);
hf.setStoredO2(mineHF);
}
public void handleLM()
{
// LM = short for Liquid Minerals
int mineLM = lm.getStoredMinerals() + (1 * upgradeLM);
lm.setStoredMinerals(mineLM);
}
// This is what's going to run the whole time on the set intervals.
public void mine()
{
mineOS = os.getStoredO2() + (1 * upgradeOS);
mineHF = hf.getStoredO2() + (1 * upgradeHF);
mineLM = lm.getStoredMinerals() + (1 * upgradeLM);
os.setStoredO2(mineOS);
hf.setStoredO2(mineHF);
lm.setStoredMinerals(mineLM);
}
// Using 10 seconds here to have it update as quickly as possible so I can
// see any changes. This is just here to write an output.
public void getUpgradeInfo()
{
System.out.println("Oxygen: " + (1 * upgradeOS) + " / per 10 seconds.");
System.out.println("Hydrogen: " + (1 * upgradeHF) + " / per 10 seconds.");
System.out.println("Liquid Mineral: " + (1 * upgradeLM) + " / per 10 seconds.");
}
I'm not the best naming schemes for my materials...
TL;DR: I can't figure out how to implement a thread or timer just for the above mentioned mine() method since I do not have the appropriate amount of knowledge. My if-else rules aren't too elegant, but I'll work on those of course. Basically the if-else rules should run separately from the mine() method, and you can do some AFKing without the game updating the System.out output, thus you can be floating in, for example, the Oxygen Silo upgrade menu, and you won't be bounced back to a different menu due to a thread "waking up", such as being bounced to the main menu, but the mine() method will still generate resources in the background as it should.
Any help on this, or just even a nudge in the right direction will be greatly appreciated.
To answer the question you asked, you can do something like this:
import java.util.*;
TimerTask tt = new TimerTask() {
public void run() {
mine();
}
}
Timer t = new Timer();
t.scheduleAtFixedRate(tt, 0, 1000);
Alternatively, you can use an ActionListener and the swing timer in a similar way. This has the advantage of being Thread-safe in case you build a swing gui on top
Lastly, you should check out the usage of synchronized and volatile to make sure that the variable(s) that are updated in mine() are done so in a thread-safe way
Thanks to #ControlAltDel, definite shove in the right direction. I have taken a bit of code and set it up like this:
import java.util.*;
// extends TimerTask needed
public class TimerTestOne extends TimerTask
{
// Needed
#Override
public void run()
{
TimerTestTwo ttt = new TimerTestTwo();
mine();
}
// Needed, method doesn't need the same name though.
private void completeTask()
{
try
{
//assuming it takes 10 secs to complete the task
Thread.sleep(10000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
public static void main(String[] args)
{
// You will need to define the following line of code:
TimerTask tt = new TimerTestOne();
Scanner keyboard = new Scanner(System.in);
String reply;
// Following 2 lines of code, yup, need them.
Timer timer = new Timer(true);
timer.scheduleAtFixedRate(tt, 0, 10*1000);
previousMenu();
for (int i = 0; i <= 10000; i++)
{
for (int ii = 0; ii <= 10000; i++)
{
System.out.println("Go to another menu?");
reply = keyboard.nextLine();
if (reply.equalsIgnoreCase("/yes"))
{
yes();
reply = keyboard.nextLine();
}
}
}
}
// I added the following methods, just so I didn't have to work
// off 2 class files.
public void mine()
{
System.out.println("Mined");
}
public static void yes()
{
System.out.println("Next menu");
}
public static void previousMenu()
{
System.out.println("Previous menu");
}
}
So there, if anyone ever needs to have a look at setting a timer up that won't break your text based game.
I'm using StyledText 400x100 widget and it's working like a console where the program interacts with the user.
This is how I update the widget:
private static Shell MainShell = null;
public void createPartControl(Composite parent){
MainShell = parent.getShell();
}
public static void updateConsole(final String newMessage){
if(MainShell.isDisposed() || myStyledText.isDisposed() ) return;
MainShell.getDisplay().syncExec(new Runnable(){
myStyledText.setText( newMessage + "\n" + myStyledText.getText() );
});
}
Similar to append(), but this one insert to the first line and inserts a line break "\n".
I'm using CycleBarrier to handle Threads. Currently it's running 300+ threads, and I'm allowing only 10 threads / cycle to not kill the CPU.
// divide 300/10 because there is an inner for() which runs 10 threads / cycle
for(int n = 0; n < 300/10; n++){
// allow only 10 threads to work
final CycleBarrier br = new CycleBarrier(10);
for(int i = 0; i < 10; i++){
new Thread(new MyClass(cb).start();
}
//waiting for Threads to reach the barrier
br.await();
}
And now the MyClass class:
public MyClass implements Runnable{
private CycleBarrier cb;
public MyClass(CycleBarrier cb){
this.cb = cb;
}
#Override
public void run(){
for(int i = 0; i < 256; i++){
for(int j = 0; j < 256; j++){
//View is the main class (eclipse RCP) and updateing the widget
View.updateConsole("matrix["+i+"]["+j+"]");
// Just an integer which counts the number of the loops
View.TOTAL_LOOPS++;
}
}
cb.await();
}
}
This was an example. It should write to the View widget in asynchronous ways (not in order) because the Threads doesn't reaches the barrier in order.
I'm using eclipse RCP (3.8).
ISSUE
Why the program is working correct in DEBUG mode? I have set a breakpoint where I'm starting new Threads (in the inner for() ) and I'm clicking the Resume button to start threads one by one.
When I'm trying to open in normal mode (RUN or exported) there are "leaks" (I don't know how to name), there are less lines in the console.
View.TOTAL_LOOPS
Should have in total:
256*256*10*30 = 19660800 // View.TOTAL_LOOPS++; in the MyClass
and in normal run it's having dynamic results: 174614904, 17025759, etc. In DEBUG mode it's reaching the exact value.
Question:
Are the Threads being killed?
It has nothing to do with SWT. You are incrementing a single shared variable from 10 threads at once. This is a classic example of a race condition. Since ++ isn't an atomic operation, something like this can happen:
int temp = View.TOTAL_LOOPS; // in thread 1
int temp = View.TOTAL_LOOPS; // in thread 2
int temp2 = temp + 1; // in thread 1
View.TOTAL_LOOPS = temp2; // in thread 1
int temp2 = temp + 1; // in thread 2
View.TOTAL_LOOPS = temp2; // in thread 2
Note View.TOTAL_LOOPS only increases by 1 after this, and obviously it won't happen if you start threads one-by-one.
Use an AtomicInteger instead if you just want a thread-safe counter or otherwise synchronize your threads properly.
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.
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();
}
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.