Can I do 'global Shared Object' in Java? - java

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);
}
}

Related

A thread that runs without stopping

Is it possible in java to create a thread that will always work in the background? The problem is that the application instance sometimes crashes with an OutOfMemoryException. Therefore, several instances are launched in parallel. Each instance does some work: it saves something to the database at the request of the user. And the stream, which should work constantly, will look into the database and somehow process the information from it.
Most likely, the sheduler will not work, since the thread must be running constantly and wait for a signal to start working.
First of all, I suggest you investigate and resolve the OutOfMemoryException because it better to avoid these cases. You can instanziate a thread that wait for a request, execute a request and then return to wait for another request. The implementation is like this for thread:
/** Squares integers. */
public class Squarer {
private final BlockingQueue<Integer> in;
private final BlockingQueue<SquareResult> out;
public Squarer(BlockingQueue<Integer> requests,
BlockingQueue<SquareResult> replies) {
this.in = requests;
this.out = replies;
}
public void start() {
new Thread(new Runnable() {
public void run() {
while (true) {
try {
// block until a request arrives
int x = in.take();
// compute the answer and send it back
int y = x * x;
out.put(new SquareResult(x, y));
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
}).start();
}
}
And for the caller method:
public static void main(String[] args) {
BlockingQueue<Integer> requests = new LinkedBlockingQueue<>();
BlockingQueue<SquareResult> replies = new LinkedBlockingQueue<>();
Squarer squarer = new Squarer(requests, replies);
squarer.start();
try {
// make a request
requests.put(42);
// ... maybe do something concurrently ...
// read the reply
System.out.println(replies.take());
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
To more information, you can start to read the post that I found here to provide you the example.
You basically need an infinitely running thread with some control.
I found this answer to be the simplest and it does what you need.
https://stackoverflow.com/a/2854890/11226302

Check if another Thread is interrupted, without polling

I'd like to check to see if a Thread is Interrupted, from some other Thread, without polling this to check - i.e. some kind of monitor.
Specifically, what I am trying to do is force-kill (Stop) a Thread when it is Interrupted. I will include a code example below of a trivial example of what I have done so far - it works, but polling to check if the Thread is interrupted is sub-optimal and I would like to avoid this.
public class ThreadTest
{
public static void main(final String[] args) throws InterruptedException
{
final Thread outerThread = new Thread()
{
#Override
public void run()
{
// Need to externally monitor the thread to detect and process interrupts (for cancellation)
final Thread thread = Thread.currentThread();
new Thread()
{
#Override
public void run()
{
while (true)
{
try
{
Thread.sleep(500);
}
catch (final InterruptedException e)
{}
if (thread.isInterrupted())
{
// Then kill it
thread.stop();
return;
}
}
}
}.start();
uninterruptibleForever();
}
};
outerThread.start();
// Ensure the thread has time to start up
Thread.sleep(500);
outerThread.interrupt();
// The thread should terminate at this point and not continue.
}
/** Some arbitrary task that runs forever and ignores interrupts */
public static void uninterruptibleForever()
{
while (true)
{
System.out.println(MessageFormat.format("I''m still running at {0}", new Date().toLocaleString()));
}
}
}
I can't recommend strongly enough that you don't use Thread#stop().
It should never have existed, was deprecated very quickly and frankly should have been removed about 20 years ago.
You have no idea what the thread is doing when you stop it and it is very easy to corrupt shared objects and leave external resources (e.g. files) in an invalid state.
Suppose the thread is in the middle of resizing a shared ArrayList<> there's risk the object will be corrupted and your whole program fails intermittently in ways you cannot fix.
Do not use Thread#stop() it is broken and cannot be fixed.
It's a terrible feature of Java that it leads people into invalid techniques regarding threads.
Caveat over - how about just overriding interrupt() in a sub-class?
public void interrupt(){
this.stop();
}
You've decided to sub-class Thread (rather than Runnable) so this will "work". "work" in the sense of what you're doing. Not actually work or anything.
The only valid way to solve this is have the thread you want to terminate co-operate by responding to interrupt() as an instruction to come to a suitable point and then terminate cleanly.
Or you can create another flag indicating the thread should end.
I don't know why you need to monitor the thread externally. But here is a small sample how you could do it if you really need it:
import java.util.LinkedList;
import java.util.List;
public abstract class MonitoredCallable implements Runnable {
private final List<InterruptedHandler> interruptedHandlers = new LinkedList<>();
protected abstract void runInternal() throws Exception;
#Override
public final void run() {
try {
runInternal();
} catch(Exception ex) {
}
for (InterruptedHandler interruptedHandler : interruptedHandlers) {
interruptedHandler.threadInterrupted(this);
}
}
public void addInterruptedHandler(InterruptedHandler interruptedHandler) {
this.interruptedHandlers.add(interruptedHandler);
}
public static interface InterruptedHandler {
void threadInterrupted(Thread t);
}
}
Now just use it like this:
MonitoredThread mt = new MonitoredThread() {
#Override
protected void runInternal() throws Exception {
//dosomething
}
};
mt.addInterruptedHandler(t->t.stop());

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.

thread of different class object in java

I have 2 java class "LegacyDAO" and "NewDAO" implementing Runnable. In an another class "Test" we create one object of each LegacyDAOObj and NewDAOObj.
Class Test {
public static void main(String args[]) {
LegacyDAO legacyDAOObj= new LegacyDAO();
NewDAO newDAOObj= new NewDAO();
Thread legacyDBThread= new Thread(legacyDAOObj);
Thread newDBThread= new Thread(newDAOObj);
}
}
Is there any relation between legacyDBThread and newDBThread ?
If I want newDBThread to execute some code and then wait for legacyDBThread to finish and then continue running. How can this be achieved ?
wait() and notify() API is helpful here. you can share some objects in two class and use wait-notify on these shared objects to sync two thread.
You can use countdown latch. Create a count down latch with count one, pass it to legacyDAOObj. After the logic executed in legacyDAOObj, count down the latch. Till the logic is executed in legacyDAOObj, newDAOObj awaits.
If you just want to wait for a thread to end, use Thread#join(), it seems to be the easiest way to achieve what you want.
CountdownLatch will be your best bet. Your newDaoObj will continue in main thread once legacyDaoObj finishes.
public static void main(String[] args) {
CountDownLatch start =new CountDownlatch(1);
LegacyDAO legacyDAOObj= new LegacyDAO();
NewDAO newDAOObj= new NewDAO();
new Thread(new Worker(legacyDAOObj)).start();
try {
start.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
newDAOObj.doSomething();
}
public static class Worker implements Runnable{
LegacyDAO dao;
public Worker(LegacyDAO dao) {
this.dao = dao;
}
#Override
public void run() {
try {
start.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
dao.doSomething();
start.countDown();
}
}

Alternative method to kill 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

Categories

Resources