I'm working on a Java Project using Sockets. Since the Socket Methods are Blocking Methods, I'm forced to make a multithreaded application.
As of now, I am able to read the incoming bytes from an other application. I write them into a StringBuilder. My problem is how to return this string back to my main thread. I was thinking of something like an Event, which I can call as soon as the Socket-Thread has finished reading.
I am happy for any ideas.
public class SocketRunnable implements Runnable {
private final Socket _socket;
public SocketRunnable(Socket socket){
this._socket = socket;
}
#Override
public void run() {
StringBuilder sb = new StringBuilder();
try {
BufferedReader bufferedReader =
new BufferedReader(
new InputStreamReader(
this._socket.getInputStream()));
char[] buffer = new char[100];
int amountOfBytes = bufferedReader.read(buffer, 0, 100); // blocks until the message is received.
String message = new String(buffer, 0, amountOfBytes);
sb.append(message);
} catch (IOException ex) {
Logger.getLogger(SocketRunnable.class.getName()).log(Level.SEVERE, null, ex);
}
finally{
// Return (!)
}
}
My problem is how to return this string back to my main thread.
You can't—not due to any technical obstacles, but because it doesn't make conceptual sense. Your main thread has already gone on its way and the context where your return value made sense is lost.
So, either:
your main thread must block to receive the result (but what's the point of multithreading then);
your main thread is already designed from the ground up in an event-oriented fashion and has an outer event loop which takes events off of a queue and handles them (this is true if you are building a GUI application).
What makes more sense is to make the result available to some other code. It can all happen in the same thread, the one which did the receiving. You can achieve this by simply calling an appropriate method. So, the thing to solve in your design is, how to make an instance which has that method available to the code which is executed in the reading thread.
You can use the Callable interface in conjunction with Executors.
You can read about it here:
Callable:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Callable.html
Executors:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
Just implement the callable interface with your SocketRunnable class (there is one method - call(), which will return the value from one thread to another thread upon completion).
To display the result into a Swing TextField you can process the result, once you have the string just do:
final String msg=???; // Insert your string here
SwingUtilities.invokeLater(new Runnable() {
public void run() {
textBox.setText(msg);
}
});
The invokeLater call will put you onto the correct thread to modify the contents of the text field.
Write the result String in a blocking queue, and let the main thread poll or take from that queue.
Related
Is there a way to safely and immediately stop the execution of a Thread in Java? Especially, if the logic inside the run() method of the Runnable implementation executes only a single iteration and does not regularly check for any flag that tells it to stop?
I am building a Web Application, using which a user can translate the contents of an entire document from one language to another.
Assuming the documents are extra-large, and subsequently assuming each translation is going to take a long time (say 20-25 minutes), my application creates a separate Thread for each translation that is initiated by its users. A user can see a list of active translations and decide to stop a particular translation job if he/she wishes so.
This is my Translator.java
public class Translator {
public void translate(File file, String sourceLanguage, String targetLanguage) {
//Translation happens here
//.......
//Translation ends and a new File is created.
}
}
I have created a TranslatorRunnable class which implements the Runnable interface as follows:
public class TranslatorRunnable implements Runnable {
private File document;
private String sourceLanguage;
private String targetLanguage;
public TranslatorRunnable(File document, String sourceLanguage, String targetLanguage) {
this.document = document;
this.sourceLanguage = sourceLanguage;
this.targetLanguage = targetLanguage;
}
public void run() {
// TODO Auto-generated method stub
Translator translator = new Translator();
translator.translate(this.document, this.sourceLanguage, this.targetLanguage);
System.out.println("Translator thread is finished.");
}
}
I'm creating the thread for translating a document from an outer class like this:
TranslatorRunnable tRunnable = new TranslatorRunnable(document, "ENGLISH", "FRENCH");
Thread t = new Thread(tRunnable);
t.start();
Now my problem is how do I stop a translation process (essentially a Thread) when the user clicks on "Stop" in the GUI?
I have read a few posts on StackOverflow as well as on other sites, which tell me to have a volatile boolean flag inside the Runnable implementation, which I should check on regularly from inside the run() method and decide when to stop. See this post
This doesn't work for me as the run() method is just calling the Translator.translate() method, which itself is going to take a long time. I have no option here.
The next thing I read is to use ExecutorService and use its shutDownAll() method. But even here, I'd have to handle InterruptedException somewhere regularly within my code. This, is again out of the option. Referred this documentation of the ExecutorService class.
I know I cannot use Thread.stop() as it is deprecated and may cause issues with objects that are commonly used by all threads.
What options do I have?
Is my requirement really feasible without substantial changes to my design? If yes, please tell me how.
If it is absolutely necessary for me to change the design, could anyone tell me what is the best approach I can take?
Thanks,
Sriram
Is there a way to safely and immediately stop the execution of a Thread in Java?
No. each thread is reponsible to periodically check if it has been interrupted to exit as soon as possible
if (Thread.currentThread().isInterrupted() ) {
// release resources. finish quickly what it was doing
}
if you want a more responsive application, you have to change the logic (for example divide each job in smaller batches) so each thread does this checking more often than every 20-25 minutes
If you are the one that created the Translator class what's stopping you from adding some kind of value inside the function that is checked periodically and if needed stops reading the lines from file something like this
public static List<String> readFile(String filename)
{
List<String> records = new ArrayList<>();
try
{
BufferedReader reader = new BufferedReader(new FileReader(filename));
String line;
while ((line = reader.readLine()) != null)
{
String[] split = line.split("\\s+");
records.addAll(Arrays.asList(split));
if (needsToStop) {
break; //Or throw exception
}
}
reader.close();
return records;
}
catch (Exception e)
{
System.err.format("Exception occurred trying to read '%s'.", filename);
e.printStackTrace();
return null;
}
}
I'm investigating making a framework to use a WebView to run arbitrary JavaScript. It works fine.
For programmer convenience I'd like to be able to make a synchronous call invoking a bit of JavaScript, and get the result within a single function (No comments please about code execution speed. Of course it'll be slow).
But the threading model is causing me problems. WebView makes its callbacks to the UI thread - which is nice and programmer-friendly. But it makes trouble for me. I'd like to be able to do this in the UI thread:
String four = X.invokeJavaScriptReturningString("2+2"); // result "4"
where the method is as follows:
public String invokeJavaScriptReturningString( final String javaScript) throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(1);
final String[] result = new String[1]; // Kludge - array is assignable from nested class.
ValueCallback<String> callback = new ValueCallback<String>() {
#Override
public void onReceiveValue(String s) {
result[0] = s;
latch.countDown();
}
};
mWebView.evaluateJavascript(javaScript, callback);
latch.await(99, TimeUnit.SECONDS);
return result[0];
}
But of course the callback message gets queued in the UI thread message queue, and the function blocks for 99 seconds then returns null.
Some message-based thread models have a way to work around this; something like:
while (!latch.await(1, TimeUnit.MILLISECONDS) {
// Process any messages in the UI thread Looper queue.
}
But I can't find any way to get at the Android Looper queue.
Any suggestions how to solve this?
I'm working on my first multi-threaded application, for the sake of learning. I really need to learn it. I already have a single-threaded function that reads in all text files in a directory, and replaces all indentation tabs to three spaces.
It has the ability to pass in an Appendable for the sake of optional extra information (listing each file, giving statistics, etcetera). If they pass in null, they want no debugging.
I'm trying to determine what's the best way of handling this in a multi-threaded version, but searching for "debugging multi-threaded java" is giving me nothing but how to diagnose bugs and deadlocks.
Can I safely stick with an Appendable or should I be considering something else? I'm not sure how to deal with interleaving messages, but the first thing I want to figure out is thread safety.
Rather than passing in an Appendable, consider using slf4j in your library to do the logging.
If no logging framework is linked in at run-time, no logging will be done. If the application is doing logging already, then there's probably a front-end to it that slf4j will output to.
I'd recommend using Logback for your logging output, as it's nicely configurable, either through configuration files or directly in code. All you need to do to get rudimentary output is include the JAR.
Debugging threads is often a case of trying to figure out presentation. Log4j is great generally. You can configure it to tag each line with the thread name as well as the timestamp. Once you do this you can filter the output based on thread name and follow a single thread.
A good filtering tool is really important. The most basic would be tail and pipe it through grep--but if it's something you do a lot you might want to layer something on top of the log--like a GUI with tabs for each thread or something like that.
Log4j itself will have no problem dealing with threads.
If you really want to do it yourself, pass in a DIFFERENT appendable to each thread, then when the thread is done dump it or save it to a file. You probably want to use just one thread to dump/save the appendables.
The problem with using Appendable from multiple threads is that it is not specified as thread safe.
Thread safety is the responsibility of classes that extend and implement this interface.
The answer is therefore to use a thread-safe multiplexor. This one uses a BlockingQueue and a thread that pulls data out of it and forwards it to their Appendable.
class TellThemWhatIsHappening implements Appendable {
// The pipe to their system/log.
private final Appendable them;
// My internal queue.
private final BlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
// Hav I been interrupted?
private volatile boolean interrupted = false;
public TellThemWhatIsHappening(Appendable them) {
// Record the target Appendable.
this.them = them;
// Grow my thread.
Thread t = new Thread(consumer);
// Make sure it doesn't hold your app open.
t.setDaemon(true);
// Start the consumer runnning.
t.start();
}
// The runnable that consumes the queue and passes it on to them.
private Runnable consumer = new Runnable() {
#Override
public void run() {
while (!interrupted) {
try {
// Pull from the queue and push to them.
them.append(queue.take());
} catch (InterruptedException ex) {
// We got interrupted.
interrupted = true;
} catch (IOException ex) {
// Not sure what you shoudl do here. Their appendable threw youy an exception.
interrupted = true;
}
}
}
};
Continued...
private void append(String s) throws IOException {
// No point if they are null.
if (them != null) {
try {
queue.put(s);
} catch (InterruptedException ex) {
// What should we do here?
interrupted = true;
}
}
}
#Override
public Appendable append(CharSequence csq) throws IOException {
append(csq.toString());
return this;
}
#Override
public Appendable append(CharSequence csq, int start, int end) throws IOException {
append(csq.subSequence(start, end).toString());
return this;
}
#Override
public Appendable append(char c) throws IOException {
append("" + c);
return this;
}
}
However - it is a very good idea to use a proper logging system for logging rather than growing your own.
I am trying to create a java socket program with multithread concept.
Every single connection from client to the server is a thread.
Every client send their information to server.
I want to ask how to collect all value from the threads and put them all in an array of string?
Is needed to synchronized all this threads?
What the different if use only Thread t = new Thread() instead of Thread[] t = new Thread(client)?
Am i right for the beginning step with use Thread[] to collect all item from the threads?
Is it useful to use thread join()?
This is part which create thread,
public void listenSocket(int client){
int i=0;
Thread[] t = new Thread[client];
while(i<client){
ClientWorker w;
try{
w = new ClientWorker(server.accept());
t[i] = new Thread(w);
t[i].start();
System.out.println(t[i].getName());
} catch (IOException e) {
System.out.println("Accept failed: 4444");
System.exit(-1);
}
i++;
}
}
This is the part of what the thread doing
class ClientWorker implements Runnable{
Socket client;
String ip;
String load;
String data[]=new String[7];
ClientWorker(Socket client){
this.client = client;
}
public void setIP(String ip){
this.ip = ip;
}
public void setData(String load){
this.load = load;
}
public void getIP(){
System.out.println(ip);
}
public void getData(){
System.out.println(load);
}
public void run(){
BufferedReader in = null;
PrintWriter out = null;
XmlGenerator xml = new XmlGenerator();
try{
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
out = new PrintWriter(client.getOutputStream(), true);
} catch (IOException e) {
System.out.println("in or out failed");
}
while(true){
try{
String a = in.readLine();
setData(a);
String b = client.getRemoteSocketAddress().toString();
setIP(b);
out.println(a);
getData();
getIP();
}
catch (IOException e) {
System.out.println("Read failed");
}
}
}
}`
i've read the topic about sync,callable thread but i found nothing.
sorry for repost.
There are two ways to answer this:
First way:
I want to ask how to collect all value from the threads and put them all in an array of string? Is needed to synchronized all this threads?
If you are going to collect the results that way, then yes it is necessary to explicitly synchronize the threads' use of that array.
What the different if use only Thread t = new Thread() instead of Thread[] t = new Thread(client)?
It is not clear what you mean, but either way if you have two threads accessing / updating the same data structure then they need to synchronize for the application to be reliable / portable.
Am i right for the beginning step with use Thread[] to collect all item from the threads?
It is one approach. But there are better approaches.
Is it useful to use thread join()?
If you are going to try to address this problem at this level, then it could be useful.
The problem is that your code doesn't give me much confidence that you have a clear idea of what you are doing. Or to put it another way, there is no evidence of a design. And it is not really possible to give you specific advice if we can't figure out how you think your code should work. The code certainly doesn't seem to line up with the things you are saying at the start of your question ...
The Second way to answer this is that from Java 5 onwards, the "java.util.concurrent" package provides a broad range of "off the shelf" components for implementing multi-threaded systems. What you seem to be trying to implement sounds like a good match for an ExecutorService. It can deal with all of the low-level details of creating and managing threads, and allows the application to get the results of each computation back via a Future. This takes away the need for explicit synchronization ... the ExecutorService and Future implementations take care of that.
So, my recommendation would be to read the Javadocs for ExecutorService, etcetera and figure out how to do what you are trying to do using that. Your code is likely to be better if you do it that way.
I am writing a content distribution network in java. I have a Link class to manage sockets between two nodes in the system. There are two programs, RouterNode and DiscoveryNode.
When a router node starts up, the first thing it does is try to initialize a connection to the discovery node:
public RouterNode(int num)
{
myNumber = num;
input = new Scanner(System.in);
try {
discoveryServer = new Socket("MONDAY-PC", 60111);
myServerLink = new Link(this, discoveryServer);
} catch (IOException e) {
System.out.println("Socket could not be opened. Node terminating.");
System.exit(-1);
}
There is more to the constructor, but my problem keeps my program from getting past this try block.
The constructor of the link class (called on the line 'myServerLink = new Link(this, discoveryServer); ) looks as such:
public Link(Node n, Socket s)
{
parentNode = n;
regSocket = s;
try {
out = new DataOutputStream(regSocket.getOutputStream());
in = new DataInputStream(regSocket.getInputStream());
} catch (IOException e) {
System.out.println("Data Streams could not be created on the link.");
e.printStackTrace();
}
new Thread(new LinkListenerThread(this, in)).run();
}
where the last line of this constructor starts a new thread that is designed to listen on the socket for incoming messages that are being passed.
The run() method in LinkListenerThread stars as follows:
#Override
public void run()
{
byte[] message;
System.out.println("Link now active and running.");
while(!done)
{
System.out.println("attempting to read from socket...");
try {
// read now many bytes the following message will be
byte[] messageLengthBytes = new byte[4];
in.read(messageLengthBytes, 0, 4);
My problem is that once I instantiate the link from the router node, it's execution stops from what seems to be the LinkListenerThread blocking it when it calls in.read(). This listener is running on a separate thread so I am not sure if this is actually something strange with threads, or it is just an example of my lack of experience with them.
I have another instance in my program where I am reading on a separate thread
Could this be caused because the node classes aren't explicitly implementing runnable and therefore are not on their own threads?
Any help is greatly appreciated.
Edit 1: I have made the Node classes implement Runnable and starting them on their own threads, but it still locks up when the in.read() is called;
You intend to start a thread by calling Thread.run() method instead of Thread.start(). And this makes your program single-threaded, then the I/O ops block the only thread(the main thread) in the try-catch clause if there is no data coming in or the while loop never ends.
Just use Thread.start() to start a thread can fix your problem.
The problem has been resolved by using .start() instead of .run()
It all boiled down to a misunderstanding of how to instantiate threads in java.