Establishing a Connection Asynchronously [duplicate] - java

This question already has answers here:
What is the difference between Thread.start() and Thread.run()?
(9 answers)
Closed 6 years ago.
I was told to run all of my MySQL connection processes on another thread besides the main thread to avoid the main thread from being stuck on a process that takes a few seconds to process.
Therefore, I established a ConnectionPool in a separate thread, so that my GUI launches independently from the establishment of the connection. However, this is not the case. When I run the program, it waits until the connection is established and then it actually runs launch(args); My concern is why is it not running independently when a new thread is being established?
public static void main(String[] args) {
initiateConnection();
launch(args);
}
private static void initiateConnection() {
new Thread(() -> {
try {
connection = new ConnectionPool("jdbc:mysql://127.0.0.0/comm", "root",
"pass");
} catch (Exception e) {
}
}).run();
}

From Javadocs of Thread.run()
If this thread was constructed using a separate Runnable run object, then that Runnable object's run method is called; otherwise, this method does nothing and returns.
So, only the body of lambda expression (which is actually body of the method run of java.lang.Runnable ) is called. It is equivalent to:
(new Runnable() {
#Override
public void run() {
try {
connection = new ConnectionPool("jdbc:mysql://127.0.0.0/comm", "root",
"pass");
} catch (Exception e) {
}
}
}).run();

You should call .start() instead of .run(). The JVM will call .run on your lambda for you.

Related

Thread runs an infinite operation which I have no control over. How to stop it? [duplicate]

This question already has answers here:
How to properly stop the Thread in Java?
(9 answers)
How to timeout a thread
(17 answers)
Closed 2 years ago.
so I am making a java code testing web application and I am running each code execution in a seperate thread. The problem is that sometimes tests have a time limit or the student just writes an infinite while loop. I've tried to terminate my testing thread with "best practices" such as using interrupts but I have no control over the inner workings of my compilation function so I can't just tell the thread to look if it has been interrupted or not. I'd like advice on how to handle this situation better.
Here is my bare bones example of what I want to achieve:
public class Main {
public static void main(String[] args) {
CodeExecutionThread cex = new CodeExecutionThread();
cex.start();
try {
cex.join(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Thread should stop at this point.");
}
}
class CodeExecutionThread extends Thread {
public CodeExecutionThread() {
}
#Override
public void run() {
infinite_operation();
}
public void infinite_operation() {
while(true) {
System.out.println("thread active");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
I came accross the same problem more than once.
Probably not what you are looking for, but there is probably no better way than to use a flag inside the worker thread -- as described here for example: https://www.baeldung.com/java-thread-stop
When using a flag, there is of course a contract between the main thread and the worker -- you need to divide the infinite_operation into smaller chunks and check for the flag.
If you do not want that kind of contract or if it is not possible, consider using a process, which can be "safely" killed by OS (https://www.baeldung.com/java-process-api).

Why UI freezes? [duplicate]

This question already has answers here:
What's the difference between Thread start() and Runnable run()
(14 answers)
Closed 5 years ago.
I wont to run my thread in background but it keeps blocking UI.
In methods login() and dostaff() I use selenium webdriver to get data and display it in label, after that I refresh page and thread sleeps for 60000ms;
public static class Moderate implements Runnable {
public void run() {
login();
while (true) {
dostaff();
try {
Thread.sleep(60000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void login(){....};
private void dostaff(){....};
}
and I call it:
public void ModerateLoop(javafx.scene.control.Label lbl) {
this.displayLabel = lbl;
Moderate thread = new Moderate();
thread.run();
}
because you are calling the method run
thread.run();
so this is blocking the invoking thread until your code in the run method is done.
you need instead to start the thread
thread.start();

Java access object outside thread

I want to access the instance created in t1 from outside the thread, is this possible? So I can close the socket after the thread is executed.
Network class:
public class Network {
Socket socket;
public void changeConnection(String command)
throws Exception { // Whatever exceptions might be thrown
if (command.equals("connect")) {
socket = new Socket(server, port);
}
else if (command.equals("disconnect")) {
socket.close();
}
}
}
Main class:
public class Project1 {
public static void main(String[] args) throws Exception {
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
try {
Network network = new Network();
network.connect("connect");
}
catch (Exception ex) {
}
}
});
t1.start();
Thread.sleep(20000);
network.connect("disconnect");
}
}
Yes, that's possible.
In your code, the t1 variable is local to main(String[] args):
public static void main(String[] args) {
Thread t1 = ...
}
You cannot access local variables from outside the method where they are declared. In order to do so, you just need to turn the local variable into a class member (also known as field or class property). Then you can set the access modifier to define which classes can access it.
public class Project1 {
protected static Thread t1;
public static void main(String[] args) {
t1 = new Thread...
}
}
The t1 inside main() refers to the class member t1. Of course, because your main() method is static, you also need the class member you want to access from within main() to be static. You can set the access modifier of t1.
Another way to do it
But if you want to close the connection after the thread is executed, then why don't you just close it as the last statement of the thread?
public static void main(String[] args) throws Exception {
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
try {
Network network = new Network();
network.changeConnection("connect");
// Do loads of work...
// All work has been done and we're done with the
// connection. Why don't we close it just now?
network.changeConnection("disconnect");
}
catch (Exception exc) {
// Catch the exception properly
}
}
});
t1.start();
}
Or using a lambda expression:
Thread t1 = new Thread(() -> {
// body of run()
});
t1.start();
PS: You should always start class names (like Project1) with an uppercase character.
Why you want to open the socket connection in new thread as a non-static object? Because if you are opening the connection then certainly you want to close the connection.
Now if you are opening it in a new thread and as non-static socket connection object then you have keep your main thread alive who is holding the object/handler of the your socket connection so that in the end you can close it, otherwise socket connection will never be closed and the resources and RAM area it had occupied will never be freed.
Disclaimer: Without understanding your complete requirement it is hard to give you a fitting solution but my speculative solutions for you are as below, choose which fits your case/requirement:
One approach:
Generally, database connections are opened as a static object so that it can be accessed by many threads and later be closed be some/last thread. So, you can create a your SocketConnection class and create a static java.net.Socket object, which will be used by all your threads, and once everything is done over that socket connection then your last thread will close the socket connection.
Another approach (use java.lang.ThreadLocal):
If you want to pass some information/object to other pieces of code without passing it in method parameters then ThreadLocal is your friend. It will help you pass the object to any portion of code which is being executed by same thread. ThreadLocal has thread scope, so now you can understand that anything you will put in ThreadLocal will be valid until that thread is alive.
Read this nice tutorial on how to use ThreadLocal.
Another approach (solely based on the code example you used):
I guess you are using Thread.sleep(20000); so that by this sleep is over your thread t1 would have finished opening socket connection, and then you can do something, and at-last close socket connection.
If that is the case, then using sleep() method like this is not recommended. So, after thread has started, you can check if it has finished execution, and if yes then you can do whatever you wish. Below is code example:
final Network network = new Network();
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("Thread started...");
try {
network.changeConnection("connect");
}
catch (Exception ex) {
}
}
});
t1.start();
System.out.println("Thread start command executed...");
//Thread.sleep(20000);
while(t1.isAlive()){
//Do nothing...
}
network.changeConnection("disconnect");
As I think your problem, the solution should be like this.
Main class:
public class project1 {
static Thread t1 = null;
public static void main(String[] args) throws Exception {
t1 = new Thread(new Runnable() {
public void run() {
try {
network network = new network();
network.connect("connect");
}
catch (Exception ex) {
}
}
});
t1.start();
Thread.sleep(20000);
network.connect("disconnect");
}
}
Now you can access it anywhere in Project1 class.

Where to close connection/file/logs with multiple threads?

Assume the following pseudo code for a simple two thread scenario:
I have two threads, I would like to insert data to different tables to database. On thread1, I would like to insert to some table, at same time, I want to insert other data to thread 2. My question is how/where to place connection.close(), if I place it on thread 1 and it executes while thread2 is still processing, or vice versa, if thread2 has finished and closed the connection, yet thread1 hasn't finished.
Note, the database is just an example, it can be anything like a file,logger..etc.
class Thread1{
DataBaseConnection connection;
main(){
threadPool = Executors.newFixedThreadPool(1);
connection.open();
if(ThisMightTakeSomeTime)
threadPool.submit(new MyRunnable(connection));
InsertDataToDataBase(Table A, Table B));
connection.Close(); //What if thread2 isn't done yet?
}
}
public class MyRunnable implements Runnable {
MyRunnable(connection){}
#override
void Run() { ...}
void TaskThatMayTakeWhile(){
...get data ...
...Connection.InsertToTables(table X, table Y)
}
}
My question is how/where to place connection.close(),
To start, as far as I know, you should not be sharing a single connection with 2 different threads. Each thread should have it's own database connection, possibly utilizing a database connection pool such as Apache's DBCP.
Once you have multiple connections, I would have each thread manage and release its own connection back to the pool. You should make sure this is done in a finally block to make sure that if there is a database exception, the connection is still released.
If you are forced to have multiple threads share the same connection then they will have to use synchronized to make sure they have an exclusive lock to it:
synchronized (connection) {
// use the connection
}
As to when to close it if it is shared, you could have a shared usage counter (maybe an AtomicInteger) and close it when the counter goes to 0. Or as others have recommended you could use a thread-pool and then the thread pool is done free the connection.
Note, the database is just an example, it can be anything like a file,logger..etc.
In terms of a more generic answer I always try to mirror where the thing is created. If a method opens the stream then it should have the finally that closes the stream.
public void someMethod() {
InputStream stream = ...
try {
// process the stream here probably by calling other methods
} finally {
// stream should be closed in the same method for parity
stream.close();
}
}
The exception to this pattern is a thread handler. Then the Thread should close the stream or release connection in a finally block at the end of the run() or call() method.
public void serverLoopMethod() {
while (weAcceptConnections) {
Connection connection = accept(...);
threadPool.submit(new ConnectionHandler(connection);
}
}
...
private static class ConnectionHandler implements Runnable {
private Connection connection;
public ConnectionHandler(Connection connection) {
this.connection = connection;
}
// run (or call) method executed in another thread
public void run() {
try {
// work with the connection probably by calling other methods
} finally {
// connection is closed at the end of the thread run method
connection.close();
}
}
}
If you run your code it's likely that database connection will be closed before insert statement execution and of course insert will be unsuccessful.
Proper solutions
If you have multiple insert tasks:
Use ExecutorService instead of Execuutor
Submit all tasks
Invoke executorService.shutdown() it will wait until all submitted tasks are done.
Close connection
If you have only one task to submit:
You should close the connection after Connection.InsertToTables(table X, table Y) in your task.
Good for both scenarios and recommended:
Each tasks has it own connection.
Example:
class Thread1 {
private static DataSource dataSource; // initialize it
public static void main(String[] args){
ExecutorService threadPool = Executors.newFixedThreadPool(1);
threadPool.submit(new MyRunnable(dataSource));
}
}
class MyRunnable implements Runnable {
private final DataSource dataSource;
MyRunnable(DataSource dataSource) {
this.dataSource = dataSource;
}
public void run() {
Connection connection = dataSource.getConnection();
// do something with connection
connection.close();
}
}
class Thread1{
DataBaseConnection connection;
main(){
threadPool = Executors.newFixedThreadPool(1);
connection.open();
if(ThisMightTakeSomeTime)
Future f = threadPool.submit(new MyRunnable(connection));
InsertDataToDataBase(Table A, Table B));
f.get(); // this will hold the program until the Thread finishes.
connection.Close(); //What if thread2 isn't done yet?
}
}
the Future is the reference resulting from the submit call. if we call Future.get(), that will block the current thread until the submited thread finishes.

Thread and public void run() method in java [duplicate]

This question already has answers here:
How to start anonymous thread class
(9 answers)
Closed 9 years ago.
public Thread thread = new Thread();
public void start() {
running = true;
thread.start();
}
public void run() {
while(running) {
System.out.println("test");
try {
thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
My problem is that the program will not print out "test" nor will it seem to loop despite 'running' being true. Is there a way I can continuously loop in the run method?
You haven't actually asked run() to be called. All you've done is declare a run() method unrelated to the Thread.
Put your run() method in a Runnable and pass that to the Thread.
public Thread thread = new Thread(new Runnable() {
public void run() {
while (running) {
System.out.println("test");
try {
thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
The problem appears to be that you aren't running the run method that you think you're running in the thread.
First, you've created a Thread called thread. In your class's start method, you set running to true and call thread.start(). But that just calls Thread's run() method, which does nothing.
public void run()
If this thread was constructed using a separate
Runnable run object, then that Runnable object's run method is called;
otherwise, this method does nothing and returns.
You aren't calling your own run method.
You have created a run method. I can't see your class definition here, but I'm assuming that your class implements Runnable. You need to send an instance of your class as an argument to the Thread, by using the Thread constructor that takes a Runnable. Then the Thread will know to run your Runnable's run() method.
Well you need to call start() to start the thread. Otherwise neither running will be true
nor thread.start() get executed. Well i can guess you were intended to do something like this:
class MyTask implements Runnable
{
boolean running = false;
public void start() {
running = true;
new Thread(this).start();
}
public void run() {
while(running) {
System.out.println("test");
try {
Thread.sleep(1000);
// you were doing thread.sleep()! sleep is a static function
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args)
{
new MyTask().start();
}
}

Categories

Resources