i tried to add 1 to "global counter" by every Thread. So the result of "global counter" must be 10.
I printout every thread result. Most time the last result is 10. but some time the 10 is not the last number. I used synchronized or lock, but its not working.
Thank you. I hope my english is not too bad.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Hauptprogramm {
public static final int MAX_THREADS = 10;
public static int globalCounter;
public static void main(String[] args) {
// create a pool of threads, 10 max jobs will execute in parallel
ExecutorService threadPool = Executors.newFixedThreadPool(MAX_THREADS);
// submit jobs to be executing by the pool
for (int i = 0; i < MAX_THREADS; i++) {
threadPool.submit(new Runnable() {
public void run() {
// some code to run in parallel
globalCounter++;
String originalName = Thread.currentThread().getName();
System.out.println("Result: "+globalCounter+" "+originalName);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
});
}
threadPool.shutdown();
}
}
I was wandered what has been expected from this test, as I don't have 50 reputation yet, I can not add comments.
Java thread is running in JVM where there's no control in resource allocation from high level, if you are inquired to have thread that start execution after another, use release-lock mechanism, but there's no guarantee that it will do sequentially, if you inquired to do it sequentially you need to do some logic for recognition of what thread required to be executed after one another.
i think this is right now:
public void run() {
synchronized(Hauptprogramm.class)
{
globalCounter++;
String originalName = Thread.currentThread().getName();
System.out.println("Result: " + globalCounter + " " + originalName);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
}});
}
threadPool.shutdown();
}
}
Related
I am trying to print even odd numbers using two threads with interrupt method.
I refereed code from internet and wrote a code showing below.It prints properly but after prints 20,program is continuing it's execution.
What change do i have to make in the code to stop the execution of the program?
Without oldNum check code is working fine. Is there any logic to provide oldNum check ?
If I remove Thread.sleep(1000L) from Line-a then it only prints "Even Thread prints 20" and continue execution.What is happening here?
Provided break points inside run() method and inside for loop of main method ,run() methods break points are not hitting.Why this is happening?
In short I want to know what is the code flow here.
Thanks
Vikash
public class PrintOddEvenUsingInterrupt {
public static volatile int count;
public static void main(String[] args) throws InterruptedException {
Thread oddThread = new Thread(new OddInterruptThread(), "Odd Thread ");
Thread evenThread = new Thread(new EvenInterruptThread(),"Even Thread ");
oddThread.start();
evenThread.start();
for (int i = 0; i < 20; i++) {
count++;
oddThread.interrupt();//Break points works here
evenThread.interrupt();
Thread.sleep(1000L);// Line-a
}
}
static class OddInterruptThread implements Runnable {
public void run() {
int oldNum = 0;//Break points doesn't works here
while (true) {
try {
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
}
if (oldNum != count && count % 2 == 1) {
System.out.println(Thread.currentThread().getName()
+ " prints " + count);
oldNum = count;
}
}
}
}
static class EvenInterruptThread implements Runnable {
public void run() {
int oldNum = 0;//Break points doesn't works here
while (true) {
try {
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
}
if (oldNum != count && count % 2 == 0) {
System.out.println(Thread.currentThread().getName()
+ " prints " + count);
oldNum = count;
}
}
}
}
}
The reason your program is not stopping is: while your main thread exits, your odd and even threads sleeps in infinite loop.
You will need to define a stopping condition for your threads to come out.
One way to achieve this is via using conditions.
Eg:
public volatile static boolean oddFinished = false;
public volatile static boolean evenFinished = false;
Then in your threads, instead of looping infinitely, loop against condition
while (! oddFinished){
// also change your thread sleep to sleep for fewer time interval (say 1000L or whatever your program wants to wait for)
}
Do the same for even thread...
while (! evenFinished){
// also change your thread sleep to sleep for fewer time interval (say 1000L or whatever your program wants to wait for)
}
And in the main thread, you can add the following code after your for loop ends...
oddFinished = true;
evenFinished = true;
oddThread.join();
evenThread.join();
This will allow your code to stop gracefully.
I think the simplest solution will be to make your threads demons.
Just add the following lines before starting your thteads.
oddThread.setDaemon(true);
evenThread.setDaemon(true);
And your program will exit immediately after exiting from main.
I was going through java doc description of lockInterruptibly method in ReentrantLock class. My intention was to see if the threads waiting to acquire lock are getting interrupted, may be I am doing it horribly wrong. I know there is an explicit way to call interrupt on Thread and it might be that executorService that I am using has wrapped that concept under it's API.
This behavior is seen with lock method as well
My purpose is to learn this concept in detail
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;
public class LockInterruptibly extends Thread {
static ExecutorService es = Executors.newFixedThreadPool(5);
static Lock lock1 = new java.util.concurrent.locks.ReentrantLock();
public void methodA() {
if (lock1.tryLock()) {
try {
lock1.lockInterruptibly();
System.out.println("lock acquired by " + this.getName() + " of method A");
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println("this thread " + this.getName() + " was interrupted");
e.printStackTrace();
}
} else {
System.out.println(this.getName() + "failed to acquire lock");
}
}
public void methodB() {
for (int i = 0; i < 5; i++) {
System.out.println("Printed by " + this.getName() + " - " + i);
}
lock1.unlock();
System.out.println(this.getName() + " is exiting at time " + new Date(System.currentTimeMillis()));
}
#Override
public void run() {
methodA();
methodB();
}
public static void main(String args[]) {
System.out.println(new Date(System.currentTimeMillis()));
for (int i = 0; i < 10; i++) {
Runnable r = new Thread(new LockInterruptibly());
es.submit(r);
}
System.out.println(new Date(System.currentTimeMillis()));
}
}
Now look at the console output below :
console logs showing the relative order, when each thread acquires lock and releases it
My questions is:
1)Why is this interleaving behavior? Why more than 1 thread are able to acquire lock (at least according to console output) , it's almost like a recursive behavior of acquiring locks. or is it just because console output is not in sync with what is happening actually?
2) Has it something to do with executor's way of treating time consuming threads and is normal behavior?
Thanks for your comments ! I was reading about the new Lock api and how you can try to lock before actually 'acquiring' it. So I wanted to code whether the threads are really non blocking or not. The updated code above assigns 5 threads and 10 tasks to executor. All the threads which fail to acquire lock, go on to print the 'for' loop. That means they are "not busy waiting" while the lock-acquiring thread is working in 'critical section'
In contrast I also implemented the synchronized way of doing it
import java.util.ArrayList;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Synchronized extends Thread {
static ExecutorService es = Executors.newFixedThreadPool(5);
static ArrayList<Object> toBeLocked = new ArrayList<Object>();
public void methodA() {
synchronized (toBeLocked) {
try {
System.out.println("lock acquired by " + this.getName() + " of method A");
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println("this thread " + this.getName() + "was interrupted");
}
}
for (int i = 0; i < 5; i++) {
System.out.println("Printed by " + this.getName() + " - " + i);
}
System.out.println(this.getName() + " is exiting at time " + new Date(System.currentTimeMillis()));
}
#Override
public void run() {
methodA();
}
public static void main(String args[]) {
System.out.println(new Date(System.currentTimeMillis()));
for (int i = 0; i < 10; i++) {
Runnable r = new Thread(new Synchronized());
es.submit(r);
}
System.out.println(new Date(System.currentTimeMillis()));
}
}
and found out that indeed all those threads were busy-waiting . Now with the new way of doing it I observed that all the threads which failed to acquire lock went ahead and never cared about returning .Are there any design patterns that answer both, optimum use of thread pools and being able to notify the next most worthy candidate.
enter image description here Threads are not stopped even after calling Interruption from Executors shutdownNow method.
Thread Call functionality is running in a while loop , which is checking for Interruption flag.
I tried sending Interruption flag to the running thread after a certain period, but it is still executing.I want to force stop the thread.
Can anybody tell this behavior.
Attaching the sample Java code:
public class TestExecutor {
static volatile int j = 1;
public static void main(String[] args) {
ExecutorService pool = Executors.newFixedThreadPool(5);
for (int i = 1; i <= 10; ++i) {
Future<Map<String, List<String>>> abc = pool.submit(new Callable<Map<String, List<String>>>() {
volatile boolean abortFlag = false;
#Override
public Map<String, List<String>> call() throws Exception {
while(!abortFlag){
long start = System.currentTimeMillis();
for(int k=0; k < 10e4 ;k++){
abortFlag = abort();
System.out.println(Thread.currentThread().getName() +" " +abortFlag);
}
System.out.println("counter val is:" +Thread.currentThread().getName() +" : " +j++);
long end = System.currentTimeMillis();
System.out.println("time for one execution : " +" " +Thread.currentThread().getName() +" :" +(end-start));
return null;
}
return null;
}
private boolean abort() {
if(Thread.currentThread().isInterrupted()){
return true;
}else{
return false;
}
}
});
}
pool.shutdown();
try {
if (pool.awaitTermination(3000, TimeUnit.MILLISECONDS)) {
System.out.println("task completed");
} else {
System.out.println("Forcing shutdown...");
pool.shutdownNow();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Closed");
}
}
`
You have a 'long' execution before you act on abortFlag in while(!abortFlag).
As per the loop below, you will have up to 10k print outs before you have opportunity to exit.
If your application can exit before finishing that 'long' task, then just exit the inner loop when the flag has been toggled:
for(int k=0; k < 10e4 ;k++){
abortFlag = abort();
if (abortFlag) {
break;
}
System.out.println(Thread.currentThread().getName() +" " +abortFlag);
}
shutDown() , will wait for all the active/queued tasks to complete and will not allow any new task to be submitted.
shutDownNow() , will not allow any new task and tasks still in the queue will not be run and currently running tasks/threads will be interrupted.
So,
The reason why the threads where still running even after shutdownNow is called is because threads still in the for loop will still be running since no action is taken on the abortFlag. in the for loop.
Change Code Snippet :
abortFlag = abort();
if(abortFlag){
System.out.println(Thread.currentThread().getName()+" K="+k);
break;
}
Thanks
Roshan
I am doing a sample program with wait() and notify(), but when notify() is called, more than one thread is wakes up instead of one.
The code is:
public class MyQueue<T> {
Object[] entryArr;
private volatile int addIndex;
private volatile int pending = -1;
private final Object lock = new Object();
private volatile long notifiedThreadId;
private int capacity;
public MyQueue(int capacity) {
entryArr = new Object[capacity];
this.capacity = capacity;
}
public void add(T t) {
synchronized (lock) {
if (pending >= 0) {
try {
pending++;
lock.wait();
System.out.println(notifiedThreadId + ":" + Thread.currentThread().getId());
} catch (InterruptedException e) {
e.printStackTrace();
}
} else if (pending == -1) {
pending++;
}
}
if (addIndex == capacity) { // its ok to replace existing value
addIndex = 0;
}
try {
entryArr[addIndex] = t;
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("ARRAYException:" + Thread.currentThread().getId() + ":" + pending + ":" + addIndex);
e.printStackTrace();
}
addIndex++;
synchronized (lock) {
if (pending > 0) {
pending--;
notifiedThreadId = Thread.currentThread().getId();
lock.notify();
} else if (pending == 0) {
pending--;
}
}
}
}
public class TestMyQueue {
public static void main(String args[]) {
final MyQueue<String> queue = new MyQueue<>(2);
for (int i = 0; i < 200; i++) {
Runnable r = new Runnable() {
#Override
public void run() {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
queue.add(Thread.currentThread().getName() + ":" + i);
}
}
};
Thread t = new Thread(r);
t.start();
}
}
}
After some time, I see two threads being wake up by single thread. The output looks like:
91:114
114:124
124:198
198:106
106:202
202:121
121:40
40:42
42:83
83:81
81:17
17:189
189:73
73:66
66:95
95:199
199:68
68:201
201:70
70:110
110:204
204:171
171:87
87:64
64:205
205:115
Here I see 115 thread notified two threads, and 84 thread notified two threads; because of this we are seeing the ArrayIndexOutOfBoundsException.
115:84
115:111
84:203
84:200
ARRAYException:200:199:3
ARRAYException:203:199:3
What is the issue in the program?
What is the issue in the program?
You have a couple of problems with your code that may be causing this behavior. First, as #Holder commented on, there are a lot of code segments that can be run by multiple threads simultaneously that should be protected using synchronized blocks.
For example:
if (addIndex == capacity) {
addIndex = 0;
}
If multiple threads run this then multiple threads might see addIndex == capacity and multiple would be overwriting the 0th index. Another example is:
addIndex++;
This is a classic race condition if 2 threads try to execute this statement at the same time. If addIndex was 0 beforehand, after the 2 threads execute this statement, the value of addIndex might be 1 or 2 depending on the race conditions.
Any statements that could be executed at the same time by multiple threads have to be properly locked within a synchronized block or otherwise protected. Even though you have volatile fields, there can still be race conditions because there are multiple operations being executed.
Also, a classic mistake is to use if statements when checking for over or under flows on your array. They should be while statements to make sure you don't have the class consumer producer race conditions. See my docs here or take a look at the associated SO question: Why does java.util.concurrent.ArrayBlockingQueue use 'while' loops instead of 'if' around calls to await()?
So, I ran a test and the results make no sense to me. Lets consider the following code:
ThreadStuffCounter counter_1 = new ThreadStuffCounter(1);
while(counter_1.doProceed) {
Thread.sleep(500);
Thread thread = new Thread(counter_1);
thread.start();
}
With the Runnable as follows:
package test;
public class ThreadStuffCounter implements Runnable {
public volatile boolean doProceed = true;
private int id = -1;
public volatile int i = -1;
public ThreadStuffCounter(int id) {
this.id = id;
}
#Override
public void run() {
for (i = 0; i < 10; i++) {
System.out.println("i = " + i + " in runnable id = " + id);
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
doProceed = false;
}
}
Only one instance of counter is shared between threads. It takes less time for another thread to start then even one increment to be made on the counter.doProceed should, as I understand never be set to false and the loop should continue indefinitely until I get an out of memory exception and cannot start any more threads.
How is it possible for the loop to exit?
EDIT: Modified code to make sure the answer below is correct.
package test;
public class ThreadStuffCounter implements Runnable{
public volatile boolean doProceed = true;
private int id = -1;
volatile int i = -1;
public ThreadStuffCounter(int id){
this.id = id;
}
#Override
public void run() {
i = 0;
while (i < 10){
System.out.println("i = " + i + " in runnable id = " + id +
"; from thead id = " + Thread.currentThread().getId());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
i++;
}
ThreadStuff.doProceed = false;
}
}
And
package test;
public class ThreadStuff {
public static volatile boolean doProceed = true;
public static void main (String[] args) throws InterruptedException{
ThreadStuffCounter counter_1 = new ThreadStuffCounter(1);
while(doProceed){
Thread.sleep(500);
Thread thread = new Thread(counter_1);
thread.start();
}
}
}
Also, it appears more then n threads are needed if you are running for i < n. You need however many, so that n threads increment at the same time.
When at least one of the threads executes the for loop and i value is greater or equal than 10, then doProceed variable will be false (yes, this may happen), and since it's volatile this will stop the execution of the while loop that creates and starts new threads. Then, is up to all the threads to just finish executing the code of the for loop and then finishing their execution. This seems to happen because the time to start a new thread in your environment is slower than the time for a current thread to finish its execution. Also, note that several threads may increase i value, which will accelerate the for loop execution.
Probably if you loop to a higher value (not tested) then this could generate an infinite loop and the application will break when there aren't enough resources to create and start new threads.
After some tests using the limit as 10, 50 and 1000. I noticed that when you have a bigger value, since lots of threads are created, all of them increase the value of i at the same time and i slowly starts to get closer to the limit value set in the for loop. Description of my current environment:
OS: Windows 7 Professional 64 bits
Processor: Intel(R) Core(TM) i5-2520M CPU # 2.50GHz (4 CPUs), ~2.5GHz
Ram: 8192MB