Multiple threads loading different classes using Class.forName("...") - java

I have a scenario in which I thread should monitor Clickhouse and the other one should sqlite. In order to load driver classes, I am using Class.forName("..."). Since the threads are starting at a time. I think it is going under deadlock situation..
Here is the piece of code that describes the issue.
public class ch {
public static void main(String[] args) throws Exception {
new OTTLCleaner().start(); // loading CH Driver
new CHThr().start(); // loading CH Driver
Spark.getInstance(); // loading Sqlite Driver
}
}
class OTTLCleaner extends Thread {
#Override
public void run() {
try {
System.out.println("Inside OTTL");
DBHelper.deleteTables();
...
} catch (Exception e) {
System.out.println(e);
}
}
}
class CHThr extends Thread {
#Override
public void run() {
try {
System.out.println("Inside CHThr");
DBHelper.CHConn();
...
} catch (Exception e) {
System.out.println(e);
}
}
}
class Spark implements Runnable {
private static class SingletonHelper {
private static final Spark INSTANCE = new Spark();
}
public static Spark getInstance() {
return SingletonHelper.INSTANCE;
}
private Spark() {
try {
System.out.println("Inside Spark");
DBHelper.SqliteConn();
...
} catch (Exception e) {
System.out.println(e);
}
}
#Override
public void run() {
...
}
}
class DBHelper {
public static void CHConn() throws ClassNotFoundException, SQLException {
Class.forName("ru.yandex.clickhouse.ClickHouseDriver");
System.out.println("CH");
...
}
static synchronized void SqliteConn() throws Exception {
Class.forName("org.sqlite.JDBC");
System.out.println("spark");
...
}
public static void deleteTables() throws Exception {
Class.forName("ru.yandex.clickhouse.ClickHouseDriver");
System.out.println("OTTl");
...
}
}
I added Thread.sleep in between the threads, it works. It is a bad approach in real world. I may get one more thread which may needs to load diff driver in future. What is the good approach to implement this without fail?

Related

Given the below code about Deadlock...why deadlock is not happening here and what changes should i make to occur the deadlock

public class Test15_DeadLockUsingJoinMethod {
public static void main(String[] args) throws InterruptedException {
JoinThread1 jt1=new JoinThread1(jt2);
JoinThread2 jt2=new JoinThread2(jt1);
jt1.start();
jt2.start();
}
}
class JoinThread1 extends Thread {
JoinThread2 jt2;
public JoinThread1(JoinThread2 jt2) {
this.jt2=jt2;
}
public void run() {
System.out.println("1st thread execution start");
try {
jt2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("1st thread execution stopped");
}
}
class JoinThread2 extends Thread {
JoinThread1 jt1;
public JoinThread2(JoinThread1 jt1) {
this.jt1=jt1;
}
public void run() {
System.out.println("2nd thread execution start");
try {
jt1.join();
} catch (InterruptedException e){
e.printStackTrace();
}
System.out.println("2nd thread execution stopped");
}
}
Here I want to see the deadlock condition using only join() method. I know the deadlock code using synchronized keyword. But how can we execute deadlock condition using join method?
Your code doesn´t compile, you are using jt2 in the constructor of jt1, before it is defined.
In order to get a deadlock, you should define a new constructor for JoinThread1 that do not have any parameter. So, you first define jt1 using the new constructor. Then you define jt2 passing through parameter jt1 (like you have now). Then you should define a setter for the other thread in JoinThread1.
Example:
New constructor
public JoinThread1() {
}
Setter method
public void setThread(JoinThread2 jt2){
this.jt2 = jt2;
}
Main
public static void main(String[] args) throws InterruptedException {
JoinThread1 jt1=new JoinThread1();
JoinThread2 jt2=new JoinThread2(jt1);
jt1.setThread(jt2);
jt1.start();
jt2.start();
}
After that changes,you will get a deadlock.

Java - Stop thread from a different class

I'm trying to stop a java thread from a different class, but unable to figure out. I have looked into the below links, googled a lot from past 2 days but unable to nail down. May be a simple thing which i need to change but i'm out of options and hence posting it here.
Referred Links
java external threads (outside the class file it's used)
http://tutorials.jenkov.com/java-concurrency/creating-and-starting-threads.html
http://www.java2novice.com/java_thread_examples/
While typing the question, I referred the below links as well..
Stop a thread from outside
Below is my code sample. I'm able to start the WorkerThread from the MainThread and get into the loop. But unable to stop the thread started using the StopThread class.
I've also used the volatile option suggested in the below link.
http://tutorials.jenkov.com/java-concurrency/volatile.html
I feel I'm making a simple mistake, but not able to identify it.
//class WorkerThread
package main;
public class WorkerThread implements Runnable
{
public WorkerThread() {
isRunning = true;
}
public WorkerThread(boolean False) {
isRunning = False;
}
private volatile boolean isRunning;
public synchronized void stopThread() {
isRunning = false;
}
public synchronized boolean IsThreadRunning() {
return isRunning;
}
#Override
public void run()
{
int i = 1;
while(isRunning)
{
System.out.println("Loop " + i);
i++;
try { Thread.sleep(2000); }
catch (InterruptedException e) { e.printStackTrace(); }
}
}
}
//class MainThread
package main;
public class MainThread
{
public static Thread t;
public static void main(String[] args)
{
t = new Thread(new WorkerThread());
t.start();
}
}
//class StopThread
package main;
public class StopThread
{
public static void main(String[] args)
{
//What should i write here to stop the thread started by MainThread
MainThread.t.interrupt();
}
}
public class MainThread
{
public static Thread t;
public static void main(String[] args)
{
t = new Thread(new WorkerThread());
t.start();
}
}
public class StopThread
{
public static void main(String[] args)
{
MainThread.t.interrupt();
}
}
It is not safe to call Thread.stop() it is listed as deprecated in JavaDocs
Also this may be just for the sake of this question, but why does your program have two main methods?
You have an opportunity to make use of what you defined volatile variable and gracefully come out of thread like below:
public class MainThread
{
public static WorkerThread workerThread;
public static void main(String[] args)
{
workerThread = new WorkerThread();
Thread t = new Thread(workerThread);
t.start();
}
}
public class StopThread
{
public static void main(String[] args)
{
Main.workerThread.stopThread();
}
}
Note: This solution works but not a perfect solution.
You can write and read value of isRunning variable from a properties file. This way you can have interaction between two different java processes. ThreadWorker just creates file upon initiation & and just makes attempt to read the file after that. StopThread modifies the properties file when triggered which should be picked up by ThreadWorker.
Check below example:
public class ThreadWorker implements Runnable
{
public volatile static boolean isRunning = false;
public ThreadWorker() {
Properties p = new Properties();
p.setProperty("isRunning", "1");
FileOutputStream out;
try {
//Writes all properties in appProperties file
out = new FileOutputStream("appProperties");
p.store(out, "---Thread Status----");
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void run()
{
int i = 1;
String status = "1";
while("1".equals(status))
{
status = getStatus();
System.out.println("Loop " + i);
i++;
try { Thread.sleep(2000); }
catch (InterruptedException e) { e.printStackTrace(); }
}
}
public String getStatus() {
FileInputStream in;
Properties p = new Properties();
try {
in = new FileInputStream("appProperties");
p.load(in);
return p.getProperty("isRunning");
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//class StopThread
public class StopThread
{
public static void main(String[] args)
{
Properties p = new Properties();
p.setProperty("isRunning", "0");
FileOutputStream out;
try {
out = new FileOutputStream("appProperties");
p.store(out, "---Thread Status----");
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//class StopThread
public class StopThread
{
public static void main(String[] args)
{
Properties p = new Properties();
p.setProperty("isRunning", "0");
FileOutputStream out;
try {
out = new FileOutputStream("appProperties");
p.store(out, "---Thread Status----");
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Make thread t a public member of class MainThread, and then just call MainThread.t.interrupt() from StopThread

set and get using synchronization tool error in java

i have an error in this code that's the thread set 2 value instead of one when the program start , the program mustn't set the next value before get the current
this is the main class
class DATA
{
private int value=0;
Lock lock;
Condition co;
Boolean IstReady=false;
public DATA()
{
IstReady=false;
lock = new ReentrantLock();
co=lock.newCondition();
}
public void set(int x) throws InterruptedException
{
lock.lock();// try
while(IstReady==true)
co.await();
value=x;
IstReady=true;
co.signal();
lock.unlock();
}
public int get()
{
int ret=0;
try{
lock.lock();
while(IstReady==false)
co.await();
ret=value;
co.signal();
//lock.unlock();
}
catch(Exception e)
{
System.out.println(e);
}
finally{
lock.unlock();
IstReady=false;
}
return ret;
}
}
}
}
and this the set() and get() class
class setter extends Thread
{
DATA D;
public setter(DATA X)
{
D=X;
}
#Override
public void run()
{
Random T=new Random();
while(true)
{
try {
int M=T.nextInt(1000);
System.out.println("setter set"+M);
D.set(M);
} catch (InterruptedException ex) {
Logger.getLogger(setter.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
public class Newtest {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
DATA x=new DATA();
setter s=new setter(x);
getter g=new getter(x);
s.start();
g.start();
}
}
i think the error is in the set() and get() method in DATA class

Java: Throw an exception to another Thread

I have a java code like this:
private class Uploader implements Runnable
{
// ...
public void start()
{
t.start();
}
public void run()
{
try {
while(i=in.read())
{
output.write(i); // THIS IS A BLOCKING CALL !!
}
} catch(ProtocolException e) { ... }
catch(IOException e1) { ... }
}
private void restore()
{
...
}
private class Checker implements Runnable
{
// ...
#Override
public void run()
{
// I WANT (IN A PARTICULAR MOMENT) TO THROW AN
// EXCEPTION INTO THE Uploader RUN METHOD FROM HERE,
// IS IT POSSIBLE?
}
}
}
The problem is that i have a blocking write() in the Run() method, so I have added a
new thread that checks whether or not the connection is transmitting: if it's not trasmitting I want to stop the blocking write() using the exception mechanism (throwing an exception to the other thread's run() method from the checker thread).
Is it possible?
EDIT [SOLVED]:
The only way is to brutally close the output stream and to work on the amount of written bits to check whether the connection is transmitting:
private class Uploader implements Runnable
{
private OutputStream output;
private int readedBits;
public void run()
{
try {
while(i=in.read())
{
output.write(i);
readedBits++;
}
} catch(IOException e1)
{
// ENTERS HERE IF RESTORE() IS CALLED
}
}
private void restore()
{
try {
output.close();
} catch (IOException e) {}
// Restore connection ....
}
private int getReadedBits()
{
return this.readedBits;
}
private class Checker implements Runnable
{
// ...
#Override
public void run()
{
while(true)
{
try {
Thread.sleep(timeout);
} catch (InterruptedException e1) {}
if(lastReaded >= getReadedBits())
restore();
else
lastReaded = getReadedBits();
}
}
}
}
You can make your code honor Thread.interrupt() call. See javadoc of this call.
Not exactly what you've asked for but I'd rather use java.nio and
public abstract int select(long timeout) throws IOException
to (not only) detect timeouts.
In general with blocking on I/O the only way to move on is to close the resource. As #VolkerK says, the other approach is to use non-blocking I/O, which is more difficult.
I recommend using Interrupts for this. Checker may call interrupt on Uploader class.
E.g.
private class Checker implements Runnable
{
// ...
Uploader uploader;
public Checker(Uploader uploader) {
this.uploader = uploader;
}
#Override
public void run()
{
// CHECK
if(failed) uploader.interrupt();
}
}
Documentation is here: http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html

Synchronizing infinitely looped service's initialization part

I'm trying to implement a piece of code to synchronously start looped service in Java. The idea is, code under // STARTER comment should be considered as piece of Service.go() method, so if service fails to start, I want to re-throw the exception synchronously. That piece of code should only finish in case I've tried to start the thread, waited until its execution flow reached some point and next, if there are no problems, my go() method quits and thread goes on, or, if there were problems, I can re-throw the exception caught in thread's run() method from my go() method. Here's the solution that seems to work fine, but I'm curious if it's possible to make it a couple times shorter :-)
public class Program {
private static boolean started;
private static Throwable throwable;
public static void main(String[] args) {
final Object startedSetterLock = new Object();
Thread thread = new Thread() {
public void run() {
System.out.printf("trying to start...\n");
boolean ok;
Throwable t = null;
try {
init();
ok = true;
} catch(Exception e) {
ok = false;
t = e;
}
synchronized(startedSetterLock) {
started = ok;
throwable = t;
startedSetterLock.notifyAll();
}
if(!ok) {
return;
}
while(true) {
try {
System.out.printf("working...\n");
Thread.sleep(1000);
} catch(InterruptedException e) {
System.out.printf("interrupted\n");
}
}
}
private void init() throws Exception { throw new Exception(); } // may throw
};
// STARTER
synchronized(startedSetterLock) {
thread.start();
try {
startedSetterLock.wait();
} catch(InterruptedException e) {
System.out.printf("interrupted\n");
}
}
// here I'm 100% sure that service has either started or failed to start
System.out.printf("service started: %b\n", started);
if(!started) {
throwable.printStackTrace();
}
}
}
And also, there's a reason to have initialization code executed within that thread, so, please, don't advise running initialization code explicitly in go() method and then just passing all the stuff to the thread.
Thanks!
How about overriding the Thread.start() method?
public static void main(String[] args) {
Thread t = new Thread() {
public void run() {
while (true) {
try {
System.out.printf("working...\n");
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.printf("interrupted\n");
}
}
}
#Override
public synchronized void start() {
try {
init();
} catch (Exception e) {
throw new RuntimeException(e);
}
super.start();
}
private void init() throws Exception {
throw new Exception("test");
}
};
t.start();
}

Categories

Resources