SOLVED: Sorry, problem had nothing to do with Java Threads. C3P0's ComboPooledDataSource was creating so many threads and not releasing them. After switching to DBCP2's BasicDataSource, the thread count doesn't go up anymore.
I wrote a web app and it crashes due to not able to create anymore threads. In one of the function, I have the ExecutorService creating a thread pool of 10 threads as a local variable of that function. When I monitor the threads, every time the function is called, about ~12 threads are getting created.
I then moved it to a test file and run this in multiple shells:
public static void main(String[] args) throws Exception {
testRun();
Thread.sleep(1253234234);
}
public static testRun() {
WorkQueue queue = new ThreadPool(10);
for (int i = 0; i < 10; i++) {
queue.addJob(new Runnable() {
#Override
public void run() {
System.out.println(this);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}});
}
queue.startJobs();
queue.wait(10);
}
public void wait(int seconds) {
executor.shutdown();
try {
if (!executor.awaitTermination(seconds, TimeUnit.SECONDS)) {
throw new RuntimeException("Thread pool terminated unexpectedly due to time out.");
}
} catch (InterruptedException ie) {
throw new RuntimeException("Thread interrupt event is received while waiting for termination of ThreadPool - " + ie.getMessage());
}
}
This creates 25 threads in every shell, then release only 10 after it's done. So every time this function is called, there're 15 threads that are not getting released. I'm going to guess the 15 is the maxPoolSize, and the 10 is the corePoolSize. But why aren't they all getting released when function finished?
So I thought maybe I'm not understanding this ExecutorService class and write the raw thread:
public static void main(String[] args) throws Exception {
testRun();
Thread.sleep(1253234234);
}
private static void testRun() throws Exception {
for (int i = 0; i < 10; i++) {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(5000);
System.out.println(this);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
t.start();
}
}
These now creates 27 threads for every shell and release 10 after each function finished. What am I doing wrong? How do I release these threads local to a function? Can someone point me to the right way?
Please ignore compile/syntax error as I replaced the test content after testing it, so this isn't copy and paste off of working code.
Thank you.
Related
Below is the consumer producer problem code, but the code is not working as expected. Here the consumer and producer are supposed to be just producing and consuming one object.
public class ProducerConsumer {
private static LinkedList<Integer> linkedList = new LinkedList<>();
public static void main(String a[]) throws InterruptedException {
Thread producer = new Thread(new Runnable() {
#Override
public void run() {
synchronized(this) {
while (linkedList.size() == 1) {
try {
wait();
} catch(InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Produced");
linkedList.add(1);
notify();
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread consume = new Thread(new Runnable() {
#Override
public void run() {
// produce
synchronized(this) {
while (linkedList.isEmpty()) {
try {
wait();
} catch(InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Consumed");
linkedList.removeFirst();
notify();
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
});
producer.start();
consume.start();
producer.join();
consume.join();
}
}
We get the output as : Produced
And the program hangs.
Please help with possible solutions/ explanations
Use a shared lock. In the posted code each Runnable is using itself as a lock so no actual locking takes place.
When a thread waits, another thread needs to call notify on the same lock in order to wake up the waiting thread. We know from your logging that the Producer thread does its thing, but since the notify acts on a lock that is not the same as the one the Consumer is using, the consumer thread never wakes up.
Changing the code to use a shared lock works:
import java.util.*;
public class ProducerConsumer { private static LinkedList linkedList = new LinkedList();
public static void main(String a[]) throws InterruptedException {
final Object lock = new Object();
Thread producer = new Thread(new Runnable() {
#Override
public void run() {
synchronized (lock) {
while (linkedList.size() ==1) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Produced");
linkedList.add(1);
lock.notify();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread consume = new Thread(new Runnable() {
#Override
public void run() {
// produce
synchronized (lock) {
while (linkedList.isEmpty()) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Consumed");
linkedList.removeFirst();
lock.notify();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
producer.start();
consume.start();
producer.join();
consume.join();
}
}
Output for this is:
c:\example>java ProducerConsumer
Produced
Consumed
which I think is what you're expecting.
Btw see this other answer I wrote for a dirt-simple implementation of a queue; you are better off protecting the shared data structure than putting the code in the threads accessing the data structure, especially look at how much easier the code is to write.
Concurrency means that you can not know before runtime which Thread will end first. So you can not know which of the Consumer and Producer is launched, executed or finished first.
To help you, you can use a cyclic barrier https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CyclicBarrier.html or applying the Fork/Join Framework https://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html
Your synchronized blocs just say : only one Thread at a time can execute this part of code, not execute the first and the second after.
An example of how CyclicBarrier works :
service = Executors.newFixedThreadPool(numThreadsTotal);
CyclicBarrier c = new CyclicBarrier(numThreadsToWait);
runProducer();
c.await();
runConsumer();
It will wait until the there is as much Threads as numThreadsToWait that have execute the runProducer to execute the runConsumer().
Perhaps using a Thread Pool with a size of 1 could help you, but you will loose the benefits of concurrency.
I think best what you can do, is use BlockingQueue.
I have written some Java code, which will call a C interrupt handler.
In Java thread A, I use waitFor() to wait the interrupt coming and then execute reboot.
In Java thread B, I will loop printing a counter value and sleep several milliseconds.
And I hope when I detect the interrupt, and then stop the printing in thread B at once, but failed. In fact, the system detects the interrupt in time, but the printing continues for maybe 10 seconds and then reboot. Note: reboot occurs maybe 11 seconds after the interrupt(press a button), the hardware is not fast.
Below is my code, any suggestion? Thanks!
import java.io.IOException;
class ThreadTesterA implements Runnable
{
private int counter;
private String cmds[] = new String[1];
private Process pcs;
#Override
public void run()
{
cmds[0] = "./gpio-interrupt";
try {
pcs = Runtime.getRuntime().exec(cmds);
if(pcs.waitFor() != 0) {
System.out.println("error");
} else {
ThreadTesterB.setClosed(true);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class ThreadTesterB implements Runnable
{
private int i;
private static boolean closed=false;
public static void setClosed(boolean closed)
{
closed = closed;
}
#Override
public void run()
{
// replace it with what you need to do
while (!closed) {
System.out.println("i = " + i);
i++;
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println();
}
}
public class ThreadTester
{
public static void main(String[] args) throws InterruptedException
{
Thread t1 = new Thread(new ThreadTesterA());
Thread t2 = new Thread(new ThreadTesterB());
t1.start();
t1.setPriority(Thread.MAX_PRIORITY);
//t1.join(); // wait t1 to be finished
t2.start();
//t2.join();
}
}
You're writing and reading a boolean variable (closed) from 2 different threads without any kind of synchronization. There is thus no guarantee that what you wrote in one thread is visible in the other thread. You need to either
make the boolean variable volatile
access the boolean variable (writing and reading) using blocks or methods synchronized on the same lock
use an AtomicBoolean instead of a boolean
I would use the third solution.
In my code:
public class thread1 implements Runnable {
public static void main(String[] args) {
thread1 d = new thread1();
new Thread(d).start();
Thread t1 = new Thread(d);
t1.start();
}
#Override
public void run() {
for (int i = 0; i < 3; i++) {
sleep1();
sleep2();
}
}
void sleep1() {
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
synchronized void sleep2() {
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
I ran my code and calculate its running time to finished.
The minimum time to finished was 7 seconds.
Why?
It should be 6 seconds, Because
3loops * 2seconds = 6seconds.
Because of context switching. sleep() is not a guaranteed amount of time, but is subject to other things going on in the system. It will try to come back, but may not succeed. Also, probably rounding in your IDE.
Program running time also accountable. You have put 6 secs to thread sleep. So Next thread will be executed. So context switching takes place.
Sorry if the question is quite simple. I am a beginner.
I have to create thread that calulates something, while the first thread works the other one have to measure if the first thread calculate the function in specified time. If not, it has to throw exception. Else it returns the answer.
I'd take the java.util.concurrent components - simple example
public void myMethod() {
// select some executor strategy
ExecutorService executor = Executors.newFixedThreadPool(1);
Future f = executor.submit(new Runnable() {
#Override
public void run() {
heresTheMethodToBeExecuted();
}
});
try {
f.get(1000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
// do something clever
} catch (ExecutionException e) {
// do something clever
} catch (TimeoutException e) {
// do something clever
}
}
Have your thread notify a synchronization object when it is done and have your other thread wait x number of milliseconds for it to finish.
public class Main {
private static final Object mThreadLock = new Object();
static class DoTaskThread extends Thread {
public void run() {
try {
int wait = new Random().nextInt(10000);
System.out.println("Waiting " + wait + " ms");
Thread.sleep(wait);
} catch (InterruptedException ex) {
}
synchronized (mThreadLock) {
mThreadLock.notifyAll();
}
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
synchronized (mThreadLock) {
DoTaskThread thread = new DoTaskThread();
thread.start();
try {
// Only wait 2 seconds for the thread to finish
mThreadLock.wait(2000);
} catch (InterruptedException ex) {
}
if (thread.isAlive()) {
throw new RuntimeException("thread took too long");
} else {
System.out.println("Thread finished in time");
}
}
}
}
join is a lot simpler than using a lock.
join (millis)
Waits at most millis milliseconds
for this thread to die. A timeout of 0
means to wait forever.
Example code:
Thread calcThread = new Thread(new Runnable(){
#Override
public void run() {
//some calculation
}
});
calcThread.start();
//wait at most 2secs for the calcThread to finish.
calcThread.join(2000);
//throw an exception if the calcThread hasn't completed.
if(calcThread.isAlive()){
throw new SomeException("calcThread is still running!");
}
Have a look at http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ExecutorService.html#awaitTermination(long,%20java.util.concurrent.TimeUnit) which allows you to handle this without dealing with thread synchronization yourself.
I am going through the kathy sierra SCJP 1.5 Chapter 9(threads) and there it is mentioned as:
Notice that the sleep() method can throw a checked InterruptedException
(you'll usually know if that is a possibility, since another thread has to explicitly do
the interrupting), so you must acknowledge the exception with a handle or declare
I just need a sample program to know when it happens (which i can run on my machine)?
I googled but could not find any sample code to test this functionality..
Thanks in Advance
Here's an example:
public class Test
{
public static void main (String[] args)
{
final Thread mainThread = Thread.currentThread();
Thread interruptingThread = new Thread(new Runnable() {
#Override public void run() {
// Let the main thread start to sleep
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
mainThread.interrupt();
}
});
interruptingThread.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
System.out.println("I was interrupted!");
}
}
}
To walk through it:
Set up a new thread which will sleep for a short time, then interrupt the main thread
Start that new thread
Sleep for a long-ish time (in the main thread)
Print out a diagnostic method when we're interrupted (again, in the main thread)
The sleep in the main thread isn't strictly necessary, but it means that the main thread does get to really start sleeping before it's interrupted.
public class SleepTest1 extends Thread {
#Override
public void run() {
try {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName());
Thread.sleep(1000);
Thread.currentThread().interrupt();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SleepTest1 st1 = new SleepTest1();
st1.start();
}
}