I'm using the CountDownLatch of JUC,but my app is blocked - java

I'm learning JUC,I want to calculate the total time that the program runs with five threads,but it's blocked after print "1 2 3"。please tell me what the reason is ?
In addition, if I don't call the function "isPrime(int)",The program will execute normally.
public class TestCountDownLatch {
public static void main(String[] args) {
CountDownLatch cwt = new CountDownLatch(5);
Runnable runnable = new CountDownThread(cwt);
long start = System.currentTimeMillis();
for (int i = 0; i < 5; i++) {
new Thread(runnable).start();
}
try {
cwt.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("total time :" + (end - start));
}
}
class CountDownThread implements Runnable{
private CountDownLatch countdownLatch;
private int num = 1;
public CountDownThread(CountDownLatch countdownLatch) {
this.countdownLatch = countdownLatch;
}
#Override
public void run() {
try{
while(true){
synchronized (this) {
if(num > 100){
break;
}
if(isPrime(num)){
System.out.println(num++);
}
}
}
}finally{
countdownLatch.countDown();
}
}
private boolean isPrime(int i) {
for (int j = 2; j <= (i >> 1); j++) {
if(i % j == 0){
return false;
}
}
return true;
}
}

Your Runnable run method, is only incrementing num when its prime and hence when it encounters 4 which is not prime its not incrementing num and your program is in that state for rest of period when its running. Fiddled with below mentioned piece which makes it go beyond that point and break at 100.
#Override
public void run() {
try {
while (true) {
synchronized (this) {
num++; // initially assigning int num = 0, and then doing this
if (num > 100) {
break;
}
if (isPrime(num)) {
System.out.println(num);
}
}
}
} finally {
countdownLatch.countDown();
}
}

Related

Multi-Threaded Java Based Prime Number Generator

I am working on a prime number generator that is multi-threaded. My goal for this multi-threaded process is that each process will check a single number. I do have somewhat working code, but I am having some issues with the "locking" concept in where the schedular is running 2 process's very closely to each other.
Claimed Lock: 0; Claimed Number: 75827; isPrime: false
Claimed Lock: 1; Claimed Number: 75829; isPrime: false
Claimed Lock: 2; Claimed Number: 75831; isPrime: false
Claimed Lock: 4; Claimed Number: 75835; isPrime: false
Claimed Lock: 5; Claimed Number: 75837; isPrime: false
Claimed Lock: 5; Claimed Number: 75837; isPrime: false
Claimed Lock: 3; Claimed Number: 75833; isPrime: true
Claimed Lock: 6; Claimed Number: 75839; isPrime: false.
(you can see that 2 locks - i.e. 5 get called twice - they should be disctinct)
My main goal of this program is to have 1 thread calculate 1 based prime numbers. There will be n number of threads based on what Java JVM reports back to the int cores variable inside of the code.
Here is a quick explanation of my program:
The program starts out getting the number logical cpu cores of the given computer
Creates a 2d Array of [2] [Num of CPU Cores]
Array[0][i] = Gets filled with 2k+1 (odd numbers) of potential prime numbers (doing this since 2 is the only known prime number that is even)
Array[1][i] = Gets filled with "-1" = Meaning that number is ready to be picked up by a process/thread
The program then spins up n number of threads (based on cpu core count)
A new thread that has been created is supposed to look for the next available Array[1][i] == -1 and change it to the value of 2. (2 represents a process lock and/or the number is being checked if prime or not)
-6a. The n number of child processes check if prime, and will change the Array[1][i] to either 1 or 0 (1 meaning it is prime or 0 meaning its not prime)
-6b. Child Process Terminates
Parent process - Main will busy wait until all Array[1][i] is either 1 or 0
Repeat back to step 3
What am I a missing or doing wrong with this logic? I believe I am missing something with the JVM/OS Schedular. But, I feel like I could be incorrect in this assumption as well? What could I do to remedy this issue?
Here is my Code:
Multi-Threaded Class
class MultithreadCalculate extends Thread {
public void run() {
try {
int indexNum = -1;
for (int i = 0; i < MultiThreadPrimeNumGen.cores; i++) {
if (MultiThreadPrimeNumGen.primeArray[1][i] == -1) {
MultiThreadPrimeNumGen.primeArray[1][i] = 2;
indexNum = i;
break;
}
}
boolean isPrime = true;
for (int i = 2; i < MultiThreadPrimeNumGen.primeArray[0][indexNum]; i++) {
if (MultiThreadPrimeNumGen.primeArray[0][indexNum] % i == 0) {
isPrime = false;
MultiThreadPrimeNumGen.primeArray[1][indexNum] = 0;
break;
}
}
if (isPrime) {
MultiThreadPrimeNumGen.primeArray[1][indexNum] = 1;
}
System.out.println("Thread " + Thread.currentThread().getId() + "; Claimed Lock: " + indexNum + "; Claimed Number: " + MultiThreadPrimeNumGen.primeArray[0][indexNum] + "; isPrime: " + isPrime);
}
catch (Exception e) {
System.out.println("Exception is caught");
}
}
}
Here is the main class:
public class MultiThreadPrimeNumGen {
public static int[][] primeArray;
public static int primeBase = 1;
public static int cores;
private static void fillArray() {
for (int i = 0; i < cores; i++) {
primeBase += 2;
primeArray[0][i] = primeBase;
}
for (int i = 0; i < cores; i++) {
primeArray[1][i] = -1;
}
}
public static void main(String[] args) throws FileNotFoundException {
File file = new File(System.getProperty("user.home") + "/Desktop" + "/PrimeNumber.txt");
PrintWriter out = new PrintWriter(file);
//Gets number of CPU Cores
cores = Runtime.getRuntime().availableProcessors();
System.out.println("Number of Cores: " + cores);
while (true) {
primeArray = new int[2][cores];
fillArray();
for (int i = 0; i < cores; i++) {
MultithreadCalculate multithreadCalculate = new MultithreadCalculate();
multithreadCalculate.start();
}
while (true) {
boolean flag = false;
for (int i = 0; i < cores; i++) {
if ((primeArray[1][i] == 0) || (primeArray[1][i] == 1)) {
flag = true;
} else {
flag = false;
break;
}
}
if (flag) {
break;
}
}
for (int i = 0; i < cores; i++) {
if (primeArray[1][i] == 1) {
out.println("PrimeNum: " + primeArray[0][i]);
out.flush();
}
}
}
}
}
So you want thread at the loop while filling the array:
Runnable run1 = new Runnable(){
public void run()
{
// Code to fill array
}
};
Thread thread1 = new Thread(run1);
thread1.start();
Runnable run2 = new Runnable(){
public void run()
{
// Code to fill array
}
};
Thread thread2 = new Thread2(run2);
thread2.start();
Actually, I solved my own idea without using Locks. The Idea Came from another user who posted on here: Prime Balpreet. So thank you! What I did was create getters and setters inside of the code. Here is the Modified code:
Multithreaded Class:
class MultithreadCalculate extends Thread {
int PrimeNumCalculate = -1;
int indexNum = -1;
public int getPrimeNumCalculate() {
return PrimeNumCalculate;
}
public void setPrimeNumCalculate(int primeNumCalculate) {
PrimeNumCalculate = primeNumCalculate;
}
public int getIndexNum() {
return indexNum;
}
public void setIndexNum(int indexNum) {
this.indexNum = indexNum;
}
public void run() {
try {
boolean isPrime = true;
for (int i = 2; i < getPrimeNumCalculate(); i++) {
if (getPrimeNumCalculate() % i == 0) {
isPrime = false;
MultiThreadPrimeNumGen.primeArray[0][getIndexNum()] = getPrimeNumCalculate();
MultiThreadPrimeNumGen.primeArray[1][getIndexNum()] = 0;
break;
}
}
if (isPrime) {
MultiThreadPrimeNumGen.primeArray[0][getIndexNum()] = getPrimeNumCalculate();
MultiThreadPrimeNumGen.primeArray[1][getIndexNum()] = 1;
}
System.out.println("Thread " + Thread.currentThread().getId() + "; Index: " + getIndexNum() + "; Number: " + getPrimeNumCalculate() + "; isPrime: " + isPrime);
}
catch (Exception e) {
System.out.println("Exception is caught");
}
}
}
Here is my Main Class:
public class MultiThreadPrimeNumGen {
public static int [][] primeArray;
public static int primeBase = 1;
public static int cores;
private static void fillArray() {
for (int i = 0; i < cores; i++) {
primeArray[0][i] = -1;
}
for (int i = 0; i < cores; i++) {
primeArray[1][i] = -1;
}
}
public static void main(String[] args) throws FileNotFoundException {
File file = new File(System.getProperty("user.home") + "/Desktop" + "/PrimeNumber.txt");
PrintWriter out = new PrintWriter(file);
cores = Runtime.getRuntime().availableProcessors();
System.out.println("Number of Cores: " + cores);
out.println(2);
out.flush();
while (true) {
primeArray = new int[2][cores];
fillArray();
for (int i = 0; i < cores; i++) {
MultithreadCalculate multithreadCalculate = new MultithreadCalculate();
multithreadCalculate.setPrimeNumCalculate(primeBase += 2);
multithreadCalculate.setIndexNum(i);
multithreadCalculate.start();
}
while (true) {
boolean flag = false;
for (int i = 0; i < cores; i++) {
if ((primeArray[1][i] == 0) || (primeArray[1][i] == 1)) {
flag = true;
} else {
flag = false;
break;
}
}
if (flag) {
break;
}
}
printMatrix(primeArray);
for (int i = 0; i < cores; i++) {
if (primeArray[1][i] == 1) {
out.println(primeArray[0][i]);
}
}
out.flush();
}
}
public static void printMatrix(int[][] arr) {
if (null == arr || arr.length == 0) {
return;
}
int idx = -1;
StringBuilder[] sbArr = new StringBuilder[arr.length];
for (int[] row : arr) {
sbArr[++idx] = new StringBuilder("[\t");
for (int elem : row) {
sbArr[idx].append(elem).append("\t");
}
sbArr[idx].append("]");
}
for (StringBuilder stringBuilder : sbArr) {
System.out.println(stringBuilder);
}
}
}

Print numbers 1,2,3 using thread1 and 4,5,6 using thread2, and 7,8,9 using thread3 and again 10,11,12 using thread1

I am trying a write a simple program with wait and notify in which I will create 3 threads.
The first thread should print 1, 2, 3.
The second thread should print 4, 5, 6.
The third thread should print 7, 8, 9.
After that, the first thread should print 10, 11, 12 and so on.
Below is a sample code for the same exercise, but I am unable to print the desired output.
public class MyThread2 extends Thread {
public final static Object obj = new Object();
int threadNo;
static volatile int threadNoToRun;
static volatile int counter = 1;
public MyThread2(int threadNo){
this.threadNo= threadNo;
}
#Override
public void run() {
synchronized (obj) {
try {
if(threadNoToRun != threadNo)
obj.wait();
else{
for(int i = 1 ; i < 4 ; i++){
if(threadNoToRun == threadNo){
System.out.println(threadNo + " counter value is "+counter);
counter++;
System.out.println(threadNo + " counter value is "+counter);
counter++;
System.out.println(threadNo + " counter value is "+counter);
counter++;
if(threadNoToRun == 1){
threadNoToRun = 2;
}
else if(threadNoToRun == 2){
threadNoToRun = 3;
}
else if(threadNoToRun == 3){
threadNoToRun = 1;
}
}
}
obj.notifyAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main (String args[]) {
/*
* Creating as many threads as needed.
*/
MyThread2 th1 = new MyThread2(1);
MyThread2 th2 = new MyThread2(2);
MyThread2 th3 = new MyThread2(3);
MyThread2.threadNoToRun = 1;
th1.start();
th2.start();
th3.start();
}
}
The output looks like:
1 counter value is 1
1 counter value is 2
1 counter value is 3
2 counter value is 4
2 counter value is 5
2 counter value is 6
Here, it was just a few changes.
Nonetheless, I have to point out that this kind of concurrency does NOT increase computation speed. Only one thread is alive at all times.
public class MyThread2 extends Thread {
public final static Object obj = new Object();
int threadNo;
static volatile int threadNoToRun;
static volatile int counter = 1;
public MyThread2(int threadNo) {
this.threadNo = threadNo;
}
#Override
public void run() {
synchronized (obj) {
try {
while (counter < 100) {
if (threadNoToRun != threadNo)
obj.wait();
else {
System.out.println(threadNo + " counter value is " + counter);
counter++;
System.out.println(threadNo + " counter value is " + counter);
counter++;
System.out.println(threadNo + " counter value is " + counter);
counter++;
if (threadNoToRun == 1) {
threadNoToRun = 2;
} else if (threadNoToRun == 2) {
threadNoToRun = 3;
} else if (threadNoToRun == 3) {
threadNoToRun = 1;
}
obj.notifyAll();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String args[]) {
/*
* Creating as many threads as needed.
*/
MyThread2 th1 = new MyThread2(1);
MyThread2 th2 = new MyThread2(2);
MyThread2 th3 = new MyThread2(3);
MyThread2.threadNoToRun = 1;
th1.start();
th2.start();
th3.start();
}
}

How I can launch a group of Thread in Java Code

I have a question.
I have 10000 strings and I want to perform some operation on each of them. I would like to parallelize this operations in order to make the total execution time acceptable.
I decided to create the thread. In particular, every 10 strings I launch 10 threads. For every threads I save the result in a list.
I have tried two versions of my code. This is my first version.
int size = 10000;
int cont = 0;
int n = 1;
String[] arrstr2;
int threadgroup = 10;
if (cont + threadgroup - 1 > size) {
arrstr2[i - cont] = subject.toString();
} else {
arrstr2[i - cont] = subject.toString();
}
if ((i == (threadgroup * n) - 1) || (i == size - 1)) {
cont = i + 1;
n = n + 1;
for (int j = 0; j < arrstr2.length; j++) {
Thread t = new Thread(new MyThread(arrstr2[j], l));
t.start();
try {
t.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (cont + threadgroup - 1 > size) {
arrstr2 = new String[size - i - 1];
}
}
i = i + 1;
In this version I don't get an advantages in the total execution.
This is my second version:
int size = 10000;
int cont = 0;
int n = 1;
String[] arrstr2;
int threadgroup = 10;
if (cont + threadgroup - 1 > size) {
arrstr2[i - cont] = subject.toString();
} else {
arrstr2[i - cont] = subject.toString();
}
if ((i == (threadgroup * n) - 1) || (i == size - 1)) {
cont = i + 1;
n = n + 1;
for (int j = 0; j < arrstr2.length; j++) {
Thread t = new Thread(new MyThread(arrstr2[j], l));
t.start();
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (cont + threadgroup - 1 > size) {
arrstr2 = new String[size - i - 1];
}
}
i = i + 1;
In this case I lose some information.
MyThread is a class that does some processing and puts the result in a list java:
public class MyThread implements Runnable{
String subject;
private List<String[]> l;
public MyThread(String subject, List<String[]> l) {
this.subject = subject;
this.l = l;
}
#Override
public void run() {
synchronized (l){
//do something
String[] result = new String[2];
result[0] = res0;
result[1] = res1;
l.add(result);
}
}
For my goal, this code is correct? How can I launch a group of thread in Java Code and to retrieve an acceptable time?
Here's a little example with an ExecutorService. The thread size is fixed to 10, but your can adjust it to your needs.
The StringTask basically reverses the given string.
public class Test {
private static final int THREADS = 10;
private static final int DATA_SIZE = 1000;
public static void main(String[] args) {
// Declare a new ExecutorService with a maximum of 2 threads.
ExecutorService service = Executors.newFixedThreadPool(THREADS);
// Prepare a list of Future results.
List<Future<String>> futures = new ArrayList<Future<String>>(DATA_SIZE);
// Submit the tasks and store the results.
for (int i = 0; i < DATA_SIZE; i++) {
futures.add(service.submit(new StringTask("Sample String " + i)));
}
// Accept no new tasks.
service.shutdown();
// Retrieve the actual String results.
List<String> results = new ArrayList<String>(DATA_SIZE);
try {
for (Future<String> future : futures) {
// The get() method blocks if the execution of the task is not finished.
results.add(future.get());
System.out.println(future.get());
}
} catch (ExecutionException ee) {
System.out.println("Error while getting result!");
ee.printStackTrace();
} catch (InterruptedException ie) {
System.out.println("Error while getting result!");
ie.printStackTrace();
}
}
/**
* Callable task that reverses a given String.
*/
private static final class StringTask implements Callable<String> {
private String input;
private StringTask(String input) {
super();
if (input == null) {
throw new NullPointerException();
}
this.input = input;
}
#Override
public String call() throws Exception {
StringBuilder builder = new StringBuilder();
for (int i = this.input.length() - 1; i >= 0; i--) {
builder.append(this.input.charAt(i));
}
return builder.toString();
}
}
}
I use a Callable here instead of a Runnable because the Callable allows the task to actually return a result that we can use (through the Future interface). If you only need a task executed, you can simply use a Runnable!
Maybe you might take a look at the new Java 8 Stream API.
http://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html
There you can easily parallelize such operations.
Using Java 8:
List<String> res = Arrays.toStream(arrstr2)
.parallel()
.map(s -> doWork(s))
.collect(Collectors.toList());

Why my producer thread is not completing its task?

I am working on the producer-consumer problem in Java in which the producer is writing Fibonacci numbers in the pipe and the consumer is consuming it via pipe reader and checking whether it is prime or not.
The problem is that only first 3 Fibonacci primes are generated by the code given below.
What is wrong with it?
package fibonacciprime;
import java.io.*;
import java.lang.*;
public class FibonacciPrime extends Thread {
public static void main(String[] args) throws Exception {
//final PipedOutputStream pout=new PipedOutputStream();
//final PipedInputStream pin=new PipedInputStream();
final PipedWriter pwriter = new PipedWriter();
final PipedReader preader = new PipedReader(pwriter);
//pout.connect(pin);
Thread threadA=new Thread()
{
public void run()
{
for(int i=2;i<1000;i++)
{
synchronized(pwriter)
{
try
{
int temp=5*i*i-4;
int temp1=5*i*i+4;
int p=(int)Math.sqrt(temp1)*(int)Math.sqrt(temp1);
int q=(int)Math.sqrt(temp)*(int)Math.sqrt(temp);
if(p==temp1 || q==temp)
pwriter.write(i);
}catch(Exception e){e.printStackTrace();}
}
}
try {
pwriter.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Thread threadB = new Thread()
{
public void run()
{
int flag=0;
try
{
int temp;
while( ( temp = preader.read() ) != -1)
{
//int k=pin.read();
for(int i=2;i*i < temp;i++)
{
if(temp%i==0)
{
flag=1;
break;
}
}
Thread.sleep(100);
if(flag==0)
System.out.println(temp);
}
preader.close();
}catch(Exception e){e.printStackTrace();}
}
};
threadA.start();
threadB.start();
}
}
Your producer thread is completing its task, but your consumer is buggy, so it doesn't print the appropriate values.
You declare your flag for detecting a prime number outside your while-loop, and never reset its value. Because of this, once the first non-prime number is read (8), all numbers after that will be treated as composite, even when they are prime.
You just need to move the declaration of flag inside your while-loop and your program will work:
while ((temp = preader.read()) != -1) {
int flag = 0; // moved this to inside the loop
for (int i = 2; i * i < temp; i++) {
if (temp % i == 0) {
flag = 1;
break;
}
}
Thread.sleep(100);
if (flag == 0) System.out.println(temp);
}

Ending threads in java correctly

I have a problem with Threads in Java.
I would like to write a program where there is Class Main which has ArrayList of Threads of some class (Class Task) which just writes a letter and the number. Object Main just wakes one Thread from ArrayList and let it to do something while the same object(Main) sleeps another one.
But there is one problem even if I change the Main.ACTIVE to false it does not end all of the Threads some stay on, and it's random, I just would like to make them end and write:
I am saying goodbay + character - sth like that
public class Main extends Thread {
ArrayList<Thread> threads;
static boolean ACTIVE = true;
public Main() {
super();
threads = new ArrayList<Thread>();
}
public void run(){
Object monitor = new Object();
for (int i = 0; i <= 5; i++) {
threads.add(new Thread(new Task(i + 65, monitor)));
}
long cT = System.currentTimeMillis();
for (int i = 0; i < threads.size(); i++) {
threads.get(i).start();
}
System.out.println("BEFORE synchronized(monitor)");
synchronized(monitor){
while (System.currentTimeMillis() - cT < 1000) {
try{
monitor.notify();
Thread.sleep(50);
monitor.wait();
} catch(Exception e){
e.printStackTrace();}
}
System.out.println("BEFORE ACTIVE= FALSE and after WHILE in Main");
ACTIVE = false;
for(int i = 0; i < threads.size(); i++){
System.out.println(threads.get(i).getState());
}
}
System.out.println("LAST COMMAND IN MAIN");
}
}
public static void main(String[] args) {
new Main().start();
//new Thread(new Task(65)).start();
}
}
And the Task Class
public class Task implements Runnable {
int nr;
char character;
Object monitor;
public Task(int literaASCII, Object monitor) {
this.nr = 0;
this.monitor = monitor;
character = (char) (literaASCII);
}
#Override
public void run() {
synchronized (monitor) {
while (Main.ACTIVE) {
try {
System.out.println("ENTERING WHILE IN TASK");
monitor.wait();
System.out.print(nr + "" + character + ", ");
nr++;
int r = (int) ((Math.random() * 50) + 50); // <500ms,1000ms)
Thread.sleep(r);
} catch (Exception e) {e.printStackTrace();}
monitor.notify();
System.out.println("YYYYYYYYY");
}
System.out.println("AFTER WHILE IN Task");
}
System.out.println("I am saying goodbye " + character);
}
}
I would recommend that you look at the more modern concurrency classes in java.util.concurrent package, especially ExecutorService. And read "Java Concurrency In Practice."
Your problem is for starters that ACTIVE should be marked as volatile. Any variable that is shared by multiple threads needs to somehow be synchronized or marked as volatile so that it will have a memory barrier around its reading and writing.
Another thing you can do from a boolean standpoint is to use the AtomicBoolean class instead of a volatile boolean.
Instead of a static volatile boolean, you might instead consider to have a volatile boolean for each Task object so that Main has more fine grained control over the individual tasks and you are using a static "global" variable. You could even add a task.shutdown() method to set the active flag.
Lastly, as #duffmo mentioned, you should always consider using one of the thread-pools ExecutorService if you always just want to have one thread running. Something like Executors.newFixedThreadPool(1). But I can't quite tell if you only want one thread all of the time. If you used an ExecutorService then main would just do:
ExecutorService threadPool = Executors.newFixedThreadPool(1);
List<Future> futures = new ArrayList<Future>();
for (int i = 0; i <= 5; i++) {
// the monitor would not be needed
threadPool.submit(new Task(i + 65));
}
threadPool.shutdown();
for (Future future : futures) {
// this waits for the working task to finish
future.get();
}
But if you need your background task to stop and start like it is currently doing with the monitor then this model might not work.
Now naswer is
0A, 0B, 0C, 0D, 0E, 0F, 1A, 1B, 1C, 1D, 1E, 1F, WAITING
WAITING
WAITING
WAITING
WAITING
WAITING
LAST COMMAND IN MAIN
I added sleep after starting threads
import java.util.ArrayList;
public class Main extends Thread {
ArrayList<Thread> threads;
volatile static boolean ACTIVE = true;
public Main() {
super();
threads = new ArrayList<Thread>();
}
public void run(){
Object monitor = new Object();
for (int i = 0; i <= 5; i++) {
threads.add(new Thread(new Task(i + 65, monitor)));
}
long cT = System.currentTimeMillis();
for (int i = 0; i < threads.size(); i++) {
threads.get(i).start();
}
try{Thread.sleep(50);}catch(Exception e){e.printStackTrace();}
// System.out.println("BEFORE synchronized(monitor)");
synchronized(monitor){
while (System.currentTimeMillis() - cT < 1000) {
try{
monitor.notify();
Thread.sleep(500);
monitor.wait();}catch(Exception e){e.printStackTrace();}
}
// System.out.println("BEFORE ACTIVE= FALSE and after WHILE in Main");
ACTIVE = false;
for(int i = 0; i < threads.size(); i++){
System.out.println(threads.get(i).getState());
}
}
System.out.println("LAST COMMAND IN MAIN");
}
public static void main(String[] args) {
new Main().start();
//new Thread(new Task(65)).start();
}
}
and the TASK
public class Task implements Runnable {
int nr;
char character;
Object monitor;
public Task(int literaASCII, Object monitor) {
this.nr = 0;
this.monitor = monitor;
character = (char) (literaASCII);
}
#Override
public void run() {
synchronized (monitor) {
while (Main.ACTIVE) {
try {
// System.out.println("ENTERING WHILE IN TASK");
monitor.wait();
System.out.print(nr + "" + character + ", ");
nr++;
int r = (int) ((Math.random() * 50) + 50); // <500ms,1000ms)
Thread.sleep(r);
} catch (Exception e) {e.printStackTrace();}
monitor.notify();
// System.out.println("YYYYYYYYY");
}
System.out.println("AFTER WHILE IN Task");
}
System.out.println("I am saying goodbye " + character);
}
}

Categories