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.
Related
This question already has answers here:
How to start anonymous thread class
(9 answers)
Closed 5 years ago.
This thread does not execute when I run the program. I'm wondering if there's something wrong with the code.
public static void writeToFileAsync(final String saveState, final String fileName) {
new Thread() {
public void run() {
try {
writeToFile(saveState, fileName);
} catch (IOException ex) {
}
start();
}
};
}
Also, why does NetBeans want me to put that semicolon next to the second curly brace after the start() call?
Start a thread
Your thread will only start if you call the start method explicitly. Here is the documentation Thread#start. The start method will then internally invoke the run method of your Thread.
Your code could then look like this:
public static void writeToFileAsync(final String saveState, final String fileName) {
// Create the thread
Thread fileWriter = new Thread() {
#Override
public void run() {
try {
writeToFile(saveState, fileName);
} catch (IOException ex) {
// Do nothing
}
}
};
// Start the thread
fileWriter.start();
}
And you probably want to remove the start(); call inside your run method.
Semicolon
You need the ; after the Thread creation because you are using an assignment:
Thread fileWriter = new Thread() { ... };
The concept you are using here is called anonymous class. Basically it is the same as if creating a new class like:
public class FileWriter extends Thread {
#Override
public void run() {
...
}
}
And then using it like:
Thread fileWriter = new FileWriter();
However an important difference is that your anonymous class has access to your local variables (the scope of that method). And that it is anonymous, so it's like a small single-time usage class.
Your call to the start method cannot be inside the body of your thread. You can do this:
new Thread() {
public void run() {
try {
writeToFile(saveState, fileName);
} catch (IOException ex) {
}
}
}.start(); // call the start method outside the body of you thread.
And about the semicolon, you are creating an Anonymous Class and that is its syntax:
Because an anonymous class definition is an expression, it must be
part of a statement... (This explains why there is a semicolon after
the closing brace.)
A thread simply works this way. Below is a piece of code where a thread is created as an anonymous inner type where the run method is overrided. Then by calling the start method , it automatically called the overrided run method.
public class ThreadTest {
Thread t = new Thread(){
public void run() {
System.out.println("thread is running");
};
};
public static void main(String[] args) {
ThreadTest threadTest = new ThreadTest();
threadTest.t.start();
}
}
I don't know how to make for a thread to run until the task is finished.
So i have this class:
public class MainTest {
public static void main(String[] args){
ThreadRunnable t1 = new ThreadRunnable();
Thread t2 = new Thread(t1);
t2.start();
System.out.println(3);
//here the next code to run
}
}
And another that try for example to add data in database:
public class ThreadRunnable implements Runnable{
public void run(){
//code to make the thread waits until the insert is done
//code for inserting data in database
}
}
So, inside method run() i want something like:
- try to insert data in database
- if connection to database is down, wait 5 seconds and try again
- if connection is ok, then insert data, and return successful message that data is added
Is this possible, and if yes, how?
Thanks!
You don’t need to wait for a thread. Just do the retries in a loop in your Runnable:
public void run() {
try {
while (true) {
try {
// Do database operations here
// Succeeded
break;
} catch (SQLException e) {
// Failed; log exception and try again.
logger.log(Level.INFO, "Couldn't save data.", e);
}
// Wait before trying again.
Thread.sleep(5000);
}
} catch (InterruptedException e) {
logger.log(Level.INFO, "Interrupted; exiting.", e);
}
}
Note: An interrupt is an explicit request for a thread to stop what it’s doing and self-terminate. The InterruptedException should not be caught inside the loop, because you want the loop to terminate in the event of an interrupt.
On the other hand, you do want the loop to keep executing in the event of an SQLException, so it should be caught inside the loop.
You can do something like that :
1) Add a waitFor function in your ThreadRunnable
2) Add synchronization via un LOCK variable
The code :
public class ThreadRunnable implements Runnable{
private boolean ended=false;
private final Object LOCK=new Object();
public void run(){
// do my stuff...
...
//at the end, notify the thread waiting for : it will wake up
synchronized(LOCK)
{
ended=true;
LOCK.notifyAll();
}
}
/**
Waits until the task is done
*/
public void waitFor()
{
synchronized(LOCK)
{
while(!ended)
{
//sleeps until notifAll is called (see run())
wait();
}
}
}
}
(in this code, you have to add the try/catch for the InterruptedException)
In your main :
public class MainTest {
public static void main(String[] args){
ThreadRunnable t1 = new ThreadRunnable();
Thread t2 = new Thread(t1);
t2.start();
t1.waitFor();
System.out.println(3);
//here the next code to run
}
}
I have two CLASS(each has a thread), and I want to create a queue shared between them. So one class could write some bytes to the queue, and the other can read from the SAME queue.
I tried static, and here are my codes:
public class ShareQueueTest {
public static final BlockingQueue<byte[]> memshare= new ArrayBlockingQueue<>(1000);
public static void main(String[] args){
Thread a = new Thread(){public void run(){
for(;;){
try {
memshare.put(new byte[20]);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(memshare.size());
}
}};
a.start();
}
}
And the other class is simple read from this queue.
public class ShareQueueTest2 {
public static void main(String[] args){
Thread a = new Thread(){public void run(){
for(;;){
System.out.println(ShareQueueTest.memshare.size());
}
}};
a.start();
}
}
I run it. Though one thread is putting bytes in this queue, the other is still saying the queue is empty all the time. So clearly they are referred to the different things.
ALL the thing happens in local machine.
As this question is simplified from a network scenario, so for some reason, I don't want another class to manipulate those two threads, they are blind to each other. Perhaps the only thing they know for each other is that each thread running on the same local machine, plus, they know the port numbers of the other. Under such condition, I need some methodologies to create a data structure which both of them can 'see'.
I also think of using memory address. Like one class get the memory address of the object, and the other get the object from the address and cast it to the correct data structure. Is it possible in java?
Any help will be appreciated!
Since both of your classes have a main method, it appears that you may be running these two classes in separate processes (instances of the JVM)
If you call ShareQueueTest2.main(...) from ShareQueueTest.main, it should work
If you call the two classes separately, it would spawn two separate JVMs which are two separate processes. The thread cannot communicate across processes via a shared queue.
You need to start both the threads from the same code as the other answers point out. Then you can access the shared variables and see the changes done by one thread get reflected in the other thread.
Try this :
public class ShareQueueTest {
public static final BlockingQueue<byte[]> memshare= new ArrayBlockingQueue<>(1000);
public static void subMain(String[] args){
Thread a = new Thread(){public void run(){
for(;;){
try {
memshare.put(new byte[20]);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(memshare.size());
}
}};
a.start();
}
}
public class ShareQueueTest2 {
public static void subMain(String[] args){
Thread a = new Thread(){public void run(){
for(;;){
System.out.println(ShareQueueTest.memshare.size());
}
}};
a.start();
}
}
public class Launch
{
public static void main( String[] args)
{
ShareQueueTest1.subMain(args);
ShareQueueTest2.subMain(args);
}
}
I have myThread.wait() that is in synchronzed(myThread) block. And I have Myrunner that implements runnable. I would like to tell notify() from myRunner, but it is not monitor object. Is it possible to get handle of myThread from myRunnable to make notify? Is there any other solution? Extend myRunnable from Thread and run it is not good for some reasons related on my code specific.
public class ThreadMain {
public Thread reader;
private class SerialReader implements Runnable {
public void run() {
while (true) {
try {
Thread.sleep(3000);
synchronized(this) {
System.out.println("notifying");
notify();
System.out.println("notifying done");
}
} catch (Exception e) {
System.out.println(e);
}
}
}
}
ThreadMain() {
reader = new Thread(new SerialReader());
}
public static void main(String [] args) {
ThreadMain d= new ThreadMain();
d.reader.start();
synchronized(d.reader) {
try {
d.reader.wait();
System.out.println("got notify");
} catch (Exception e) {
System.out.println(e);
}
}
}
}
Both threads should synchronize using the same object. Also, you should really not use an existing object to syncronize, but create a object to be used explicitly for synchronization, like
Object lock = new Object();
Also see https://www.securecoding.cert.org/confluence/display/java/LCK01-J.+Do+not+synchronize+on+objects+that+may+be+reused
If the lock is to be used to interact with your thread, you can put it in the thread and provide a getter for anyone to use it.
To notify() a wait()ing thread you much have a reference to the object it is wait() on and you must be able to acquire a lock on it. I suggest you also change a state which notifying and you check that state change in a loop when wait()ing.
The only other option is to change the code of the waiting thread.
I have been looking for ways to kill a thread and it appears this is the most popular approach
public class UsingFlagToShutdownThread extends Thread {
private boolean running = true;
public void run() {
while (running) {
System.out.print(".");
System.out.flush();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {}
}
System.out.println("Shutting down thread");
}
public void shutdown() {
running = false;
}
public static void main(String[] args)
throws InterruptedException {
UsingFlagToShutdownThread t = new UsingFlagToShutdownThread();
t.start();
Thread.sleep(5000);
t.shutdown();
}
}
However, if in the while loop we spawn another another object which gets populated with data (say a gui that is running and updating) then how do we call back - especially considering this method might have been called several times so we have many threads with while (running) then changing the flag for one would change it for everyone?
thanks
One approach with these problems is to have a Monitor class which handles all the threads. It can start all necessary threads (possibly at different times/when necessary) and once you want to shutdown you can call a shutdown method there which interrupt all (or some) of the threads.
Also, actually calling a Threads interrupt() method is generally a nicer approach as then it will get out of blocking actions that throw InterruptedException (wait/sleep for example). Then it will set a flag that is already there in Threads (which can be checked with isInterrupted() or checked and cleared with interrupted(). For example the following code can replace your current code:
public class UsingFlagToShutdownThread extends Thread {
public void run() {
while (!isInterrupted()) {
System.out.print(".");
System.out.flush();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) { interrupt(); }
}
System.out.println("Shutting down thread");
}
public static void main(String[] args)
throws InterruptedException {
UsingFlagToShutdownThread t = new UsingFlagToShutdownThread();
t.start();
Thread.sleep(5000);
t.interrupt();
}
}
i added a utlility class which essentially had a static map and methods.
the map was of type Long id, Thread thread. I added two methods one to add to the map and one to stop the thread via the use of interrupt. This method took the id as a parameter.
I also changed my loop logic from while true, too while ! isInterrupted. Is this approach ok or is this bad programming style/convention
thanks