how to use Thread in java? - java

i have code use googleseach API
I want to use Thread to improve speed of my program. But i have a problem
here is code
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONObject;
import com.yahoo.search.WebSearchResult;
/**
* Simple Search using Google ajax Web Services
*
* #author Daniel Jones Copyright 2006 Daniel Jones Licensed under BSD open
* source license http://www.opensource.org/licenses/bsd-license.php
*/
public class GoogleSearchEngine extends Thread {
private String queryString;
private int maxResult;
private ArrayList<String> resultGoogleArrayList = null;
public ArrayList<String> getResultGoogleArrayList() {
return resultGoogleArrayList;
}
public void setResultGoogleArrayList(ArrayList<String> resultGoogleArrayList) {
this.resultGoogleArrayList = resultGoogleArrayList;
}
public String getQueryString() {
return queryString;
}
public void setQueryString(String queryString) {
this.queryString = queryString;
}
public int getMaxResult() {
return maxResult;
}
public void setMaxResult(int maxResult) {
this.maxResult = maxResult;
}
// Put your website here
public final static String HTTP_REFERER = "http://www.example.com/";
public static ArrayList<String> makeQuery(String query, int maxResult) {
ArrayList<String> finalArray = new ArrayList<String>();
ArrayList<String> returnArray = new ArrayList<String>();
try {
query = URLEncoder.encode(query, "UTF-8");
int i = 0;
String line = "";
StringBuilder builder = new StringBuilder();
while (true) {
// Call GoogleAjaxAPI to submit the query
URL url = new URL("http://ajax.googleapis.com/ajax/services/search/web?start=" + i + "&rsz=large&v=1.0&q=" + query);
URLConnection connection = url.openConnection();
if (connection == null) {
break;
}
// Value i to stop while or Max result
if (i >= maxResult) {
break;
}
connection.addRequestProperty("Referer", HTTP_REFERER);
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(),"utf-8"));
while ((line = reader.readLine()) != null) {
builder.append(line);
}
String response = builder.toString();
JSONObject json = new JSONObject(response);
JSONArray ja = json.getJSONObject("responseData").getJSONArray("results");
for (int j = 0; j < ja.length(); j++) {
try {
JSONObject k = ja.getJSONObject(j);
// Break string into 2 parts: URL and Title by <br>
returnArray.add(k.getString("url") + "<br>" + k.getString("titleNoFormatting"));
}
catch (Exception e) {
e.printStackTrace();
}
}
i += 8;
}
// Remove objects that is over the max number result required
if (returnArray.size() > maxResult) {
for (int k=0; k<maxResult; k++){
finalArray.add(returnArray.get(k));
}
}
else
return returnArray;
return finalArray;
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
public void run() {
// TODO Auto-generated method stub
//super.run();
this.resultGoogleArrayList = GoogleSearchEngine.makeQuery(queryString, maxResult);
System.out.println("Code run here ");
}
public static void main(String[] args)
{
Thread test = new GoogleSearchEngine();
((GoogleSearchEngine) test).setQueryString("data ");
((GoogleSearchEngine) test).setMaxResult(10);
test.start();
ArrayList<String> returnGoogleArrayList = null;
returnGoogleArrayList = ((GoogleSearchEngine) test).getResultGoogleArrayList();
System.out.print("contents of al:" + returnGoogleArrayList);
}
}
when i run it, it can run into run method but it don't excute make query methor and return null array.
when i do't use Thread it can nomal .
Can you give me the reason why ? or give a sulution
Thanks

One of the main problems is that you didn't wait for the asynchronous computation to complete. You can wait by using Thread.join(), but it'll be even better if you use a Future<V>, such as a FutureTask<V> instead.
A Future represents the result of an asynchronous computation. Methods are provided to check if the computation is complete, to wait for its completion, and to retrieve the result of the computation. The result can only be retrieved using method get when the computation has completed, blocking if necessary until it is ready.
API links
Package java.util.concurrent (contains many high level concurrency utilities)
interface Future<V> (represents result of asynchronous computation)
interface RunnableFuture<V> (a Future that is Runnable)
class FutureTask<V> (implementation that wraps a Callable or Runnable object)
interface Executor ("normally used instead of explicitly creating threads")
class Executors (provides factory and utility methods)
Tutorials and lessons
Concurrency
High level concurrency objects
Concurrency utilities language guide
See also
Effective Java 2nd Edition
Item 68: Prefer executors and tasks to threads
Item 69: Prefer concurrency utilities to wait and notify

Your problem is simply that you're not waiting for the thread to perform its job, so you can't get the result. This can be fixed by simply doing
test.join();
before getting the result. Of course, that way the code isn't any faster than if you were doing everything in the main thread. Threads don't make things magically faster. You'll only get a benefit if you do multiple queries in parallel.

I believe you need to wait for the thread to complete before you can read the results.
Use Thread.join() for that purpose.

You don't wait for the thread to finish its calculation before getting the result, therefore you won't get the result.
Doing the same work in a single new thread will not be any faster than doing it in the main thread.
Doing multiple requests in multiple threads may be faster than doing them serially in a single thread.
You should avoid handling threads directly when it's much simpler to use a thread pool (via an ExecutorService implementations as returned by one of the helper methods in Executors) which gives the same benefits and keeps you from doing all the manual synchronizaton and waiting, which is very error prone.

when you call test.start(); the new thread test is started, while the original main thread continues .. you then immediately continue processing on the main thread, calling test.getResultGoogleArrayList() which at that point (immediately) is still null as the thread test is most likely still processing the method makeQuery.
what you are trying to do is not really geared towards multi-threading and you are not likely to see any performance improvements simply by executing something on its own thread.
multi-threading is only useful if you have more than one task that can be processed concurrently, whereas what you are doing fits the linear or synchronous paradigm.

Before you start trying 'to use threads to improve the speed of your program' you should understand exactly what threading is. It is not some magic tool that just makes things faster. It allows you to perform multiple tasks 'simultaneously', depending on your hardware etc. If you have a single core processor it won't be simultaneous but execution can switch from one thread to the other whenever one thread has to wait for something to happen (e.g. user interaction etc.). There are other reasons for threads to switch execution and it depends on a lot of factors, which you don't really need to know, just appreciate that you can't take anything for granted when it comes to threading (don't assume something will happen at a specific time unless you specifically tell it to do so).
In your example above you have 2 threads, the main thread and the GoogleSearchEngine thread. In the main thread you create the second thread and tell it to start. But as I said they can both run simultaneously so execution in the main thread will continue onto the next line to get the results, but the other thread may not even have started, or at least not got round to doing anything worthwhile, which is why you are getting null.
In this case there is absolutely no reason to use multiple threads. Your program does one task then ends, so it might as well do it all in one thread.
The sun java tutorial on concurrency.

It is making call to your makeQuery method but getting connection timeout exception as appended below.
Call test.join(); before printing the content to avoid abrupt ending of program. Handle this connection exception as per your need.
I would also recommend instead of using join() as an alternate you can use timed waiting mechanism like wait(timeout) or CountDounLatch.await(timeout) etc
java.net.ConnectException: Connection timed out: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
at java.net.Socket.connect(Socket.java:529)
....
....
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:570)
at at co.uk.mak.GoogleSearchEngine.makeQuery(GoogleSearchEngine.java:81)
at co.uk.mak.GoogleSearchEngine.run(GoogleSearchEngine.java:124)

Related

Java - How do I safely stop a thread in a Web App from the GUI?

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

Java Multithreading large arrays access

My main class, generates multiple threads based on some rules. (20-40 threads live for long time).
Each thread create several threads (short time ) --> I am using executer for this one.
I need to work on Multi dimension arrays in the short time threads --> I wrote it like it is in the code below --> but I think that it is not efficient since I pass it so many times to so many threads / tasks --. I tried to access it directly from the threads (by declaring it as public --> no success) --> will be happy to get comments / advices on how to improve it.
I also look at next step to return a 1 dimension array as a result (which might be better just to update it at the Assetfactory class ) --> and I am not sure how to.
please see the code below.
thanks
Paz
import java.util.concurrent.*;
import java.util.logging.Level;
public class AssetFactory implements Runnable{
private volatile boolean stop = false;
private volatile String feed ;
private double[][][] PeriodRates= new double[10][500][4];
private String TimeStr,Bid,periodicalRateIndicator;
private final BlockingQueue<String> workQueue;
ExecutorService IndicatorPool = Executors.newCachedThreadPool();
public AssetFactory(BlockingQueue<String> workQueue) {
this.workQueue = workQueue;
}
#Override
public void run(){
while (!stop) {
try{
feed = workQueue.take();
periodicalRateIndicator = CheckPeriod(TimeStr, Bid) ;
if (periodicalRateIndicator.length() >0) {
IndicatorPool.submit(new CalcMvg(periodicalRateIndicator,PeriodRates));
}
}
if ("Stop".equals(feed)) {
stop = true ;
}
} // try
catch (InterruptedException ex) {
logger.log(Level.SEVERE, null, ex);
stop = true;
}
} // while
} // run
Here is the CalcMVG class
public class CalcMvg implements Runnable {
private double [][][] PeriodRates = new double[10][500][4];
public CalcMvg(String Periods, double[][][] PeriodRates) {
System.out.println(Periods);
this.PeriodRates = PeriodRates ;
}
#Override
public void run(){
try{
// do some work with the data of PeriodRates array e.g. print it (no changes to array
System.out.println(PeriodRates[1][1][1]);
}
catch (Exception ex){
System.out.println(Thread.currentThread().getName() + ex.getMessage());
logger.log(Level.SEVERE, null, ex);
}
}//run
} // mvg class
There are several things going on here which seem to be wrong, but it is hard to give a good answer with the limited amount of code presented.
First the actual coding issues:
There is no need to define a variable as volatile if only one thread ever accesses it (stop, feed)
You should declare variables that are only used in a local context (run method) locally in that function and not globally for the whole instance (almost all variables). This allows the JIT to do various optimizations.
The InterruptedException should terminate the thread. Because it is thrown as a request to terminate the thread's work.
In your code example the workQueue doesn't seem to do anything but to put the threads to sleep or stop them. Why doesn't it just immediately feed the actual worker-threads with the required workload?
And then the code structure issues:
You use threads to feed threads with work. This is inefficient, as you only have a limited amount of cores that can actually do the work. As the execution order of threads is undefined, it is likely that the IndicatorPool is either mostly idle or overfilling with tasks that have not yet been done.
If you have a finite set of work to be done, the ExecutorCompletionService might be helpful for your task.
I think you will gain the best speed increase by redesigning the code structure. Imagine the following (assuming that I understood your question correctly):
There is a blocking queue of tasks that is fed by some data source (e.g. file-stream, network).
A set of worker-threads equal to the amount of cores is waiting on that data source for input, which is then processed and put into a completion queue.
A specific data set is the "terminator" for your work (e.g. "null"). If a thread encounters this terminator, it finishes it's loop and shuts down.
Now the following holds true for this construct:
Case 1: The data source is the bottle-neck. It cannot be speed-up by using multiple threads, as your harddisk/network won't work faster if you ask more often.
Case 2: The processing power on your machine is the bottle neck, as you cannot process more data than the worker threads/cores on your machine can handle.
In both cases the conclusion is, that the worker threads need to be the ones that seek for new data as soon as they are ready to process it. As either they need to be put on hold or they need to throttle the incoming data. This will ensure maximum throughput.
If all worker threads have terminated, the work is done. This can be i.E. tracked through the use of a CyclicBarrier or Phaser class.
Pseudo-code for the worker threads:
public void run() {
DataType e;
try {
while ((e = dataSource.next()) != null) {
process(e);
}
barrier.await();
} catch (InterruptedException ex) {
}
}
I hope this is helpful on your case.
Passing the array as an argument to the constructor is a reasonable approach, although unless you intend to copy the array it isn't necessary to initialize PeriodRates with a large array. It seems wasteful to allocate a large block of memory and then reassign its only reference straight away in the constructor. I would initialize it like this:
private final double [][][] PeriodRates;
public CalcMvg(String Periods, double[][][] PeriodRates) {
System.out.println(Periods);
this.PeriodRates = PeriodRates;
}
The other option is to define CalcMvg as an inner class of AssetFactory and declare PeriodRate as final. This would allow instances of CalcMvg to access PeriodRate in the outer instance of AssetFactory.
Returning the result is more difficult since it involves publishing the result across threads. One way to do this is to use synchronized methods:
private double[] result = null;
private synchronized void setResult(double[] result) {
this.result = result;
}
public synchronized double[] getResult() {
if (result == null) {
throw new RuntimeException("Result has not been initialized for this instance: " + this);
}
return result;
}
There are more advanced multi-threading concepts available in the Java libraries, e.g. Future, that might be appropriate in this case.
Regarding your concerns about the number of threads, allowing a library class to manage the allocation of work to a thread pool might solve this concern. Something like an Executor might help with this.

Waiting for an update

What is the best way to wait for an event/update. For example, I am waiting for this data structure to be updated before doing something. Implementing it inside a loop is not the best way since it consumes much CPU time like:
while (true) {
// keep checking the data structure
// if data structure is updated
// break;
}
// do something here
What's a simple but efficient way to implement something like this in Java?
wait-notifyAll is more efficient way than loop.
Standard idiom for wait():
synchronized (obj) {
while(condition not hold)
obj.wait();
}
But it's primitive way to control threads, you'd better use classes in java.util.concurrent package. Moreover, I will choose Chris Dail's answer if I meet such problem.
It really depends on the structure of the rest of your program. I would probably start by looking through java.util.concurrent to see if something in there suits you.
Examples of ways you could do this:
Futures - If you have some 'work' to be done, you can have a thread pool executor service to perform the work. When you call submit() to do your work, you get a future that you can check or block until the work is completed.
Queues - If you have one component doing the work and one component doing the waiting, you could have their communication done with queues. Any time one is done with working on the data, it can add to a queue. You could use the LinkedBlockingQueue and poll() for the work to be completed.
Listeners - Without concurrent at all, you could use the Listener/Observer pattern.
There are lots of different options depending on your application structure.
This is a code sample i would do.
In this logic I use join method in threads. This makes sure all the threads are joined before the execution of the main thread continues. I have put TODO for locations u need to add your code
import java.util.ArrayList;
import java.util.List;
public class MultiThread extends Thread{
public void run() {
System.out.println("Starting Thread - " + this.getName()+this.getThreadGroup());
//TODO data structure is updated here
}
public static void main(String[] args) {
List dataStructureList = new ArrayList() ;//TODO need to replace with list of data structure
//TODO dataStructureList contain list of items
Thread[] threadArr = new Thread[dataStructureList.size()];
for (int j = 0; j < threadArr.length; j++) {
threadArr[j] = new MultiThread();
threadArr[j].setName("Thread " + j);
threadArr[j].start();
}
try {
for (int j = 0; j < threadArr.length; j++) {
threadArr[j].join();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("All thread finished");
//TODO do something here
}
}
Assuming that you use multi-threading in an application. To use one object with several threads you should use synchronization. While one thread initializes data structure, other wait for finishing of initialization. This logic is usually implemented using wait/notify methods which can be called on any object.
Working thread(s):
while (initialized) {
synchronized (object) {
object.wait();
}
}
Initialization thread:
synchronized (object) {
// initialization
initialized = true;
object.notifyAll();
}
object is the data structure which should be initialized. The initialized flag used to indicate that the initialization has completed. It is better to use this flag because sometimes wait can be finished without corresponded notify.

The performance of Scala's loop-react is so poor. Why?

I just write one producer-consumer demo in scala and java. The demo shows that the performance of Scala is so poor. Is my code wrong?
Java AVG:1933534.1171935236
Scala AVG:103943.7312328648
The Scala code:
import scala.actors.Actor.actor
import scala.actors.Actor.loop
import scala.actors.Actor.react
import scala.concurrent.ops.spawn
object EventScala {
case class Event(index: Int)
def test() {
val consumer = actor {
var count = 0l
val start = System.currentTimeMillis()
loop {
react {
case Event(c) => count += 1
case "End" =>
val end = System.currentTimeMillis()
println("Scala AVG:" + count * 1000.0 / (end - start))
exit()
}
}
}
var running = true;
for (i <- 0 to 1) {
{
spawn {
while (running) {
consumer ! Event(0)
}
consumer!"End"
}
}
}
Thread.sleep(5000)
running = false
}
def main(args: Array[String]): Unit = {
test
}
}
The Java code:
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
public class EventJava {
static BlockingQueue<Event> queue = new LinkedBlockingQueue<EventJava.Event>();
static volatile boolean running = true;
static volatile Event sentinel = new Event(0);
static class Event {
final int index;
public Event(int index) {
this.index = index;
}
}
static class Consumer implements Runnable {
#Override
public void run() {
long count = 0;
long start = System.currentTimeMillis();
while (true) {
try {
Event event = queue.take();
if (event == sentinel) {
long end = System.currentTimeMillis();
System.out.println("Java AVG:" + count * 1000.0
/ (end - start));
break;
}
count++;
} catch (InterruptedException e) {
}
}
}
}
static class Producer implements Runnable {
#Override
public void run() {
while (running) {
queue.add(new Event(1));
}
queue.add(sentinel);
}
}
static void test() throws InterruptedException {
ExecutorService pool = Executors.newCachedThreadPool();
pool.submit(new Consumer());
pool.execute(new Producer());
pool.execute(new Producer());
Thread.sleep(5000);
running = false;
pool.shutdown();
}
public static void main(String[] args) throws InterruptedException {
test();
}
}
You are testing two very different codes. Let's consider Java, for instance:
while (true) {
Where's the opportunity for the other "actors" to take over the thread and do some processing of their own? This "actor" is pretty much hogging the thread. If you create 100000 of them, you'll see JVM get crushed under the weight of the competing "actors", or see some get all processing time while others languish.
Event event = queue.take();
if (event == sentinel) {
Why are you taking the event out of the queue without checking if it can be processed or not? If it couldn't be processed, you'll loose the event. If you added it back to the queue, it will end up after other events sent by the same source.
These are just two things that the Scala code does and the Java one doesn't.
Overall, this is a very un-scientific test. No warmup. Low number of iterations. Very very un-sciency. Look at google caliper or such for ideas on making better micro-benchmarks.
Once your numbers are clear: compile it into scala, and then decompile it into java. The answer may jump out.
I think in your case it may be the configuration of the actors. Try akka also.
I have a machine with 4 processors. If I run your java code, I get full processor usage on a single processor (25%). That is, you're using a single thread.
If I run your scala code I get full usage of all processors, I'm getting four threads.
So I suspect that two things are happening: you're getting contention updating count, and/or count isn't being incremented correctly.
Also, the test that you're doing in the loop is a pattern match in Scala, but is a simple equality in Java, but I suspect this is a minor part.
Actors are meant for small messages that result in meaningful computations, not for element-by-element data processing as above.
Your Actor code is really more comparable to an ExecutorService with multiple threads, where each message represents a new Runnable/Callable being submitted, rather than what you have in your Java code.
Your benchmark is really comparing "how fast a worker thread can consume an item from a queue" vs. "how fast can scala send a message to a mailbox, notify and schedule the actor, and handle the message". It's just not the same thing, and it's not fit for the same purpose.
Regardless, Scala can use Java threads too. Scala just gives you an additional (safer, simpler, and communications-based) concurrency mechanism.
loop and react both throw exceptions for the purpose of flow control. This means that there are two tasks given to the thread pool, only one of which does actual work. Exceptions are also much more expensive than regular returns, even when the JVM successfully optimizes them down to longjmps.

Java Threading Tutorial Type Question

I am fairly naive when it comes to the world of Java Threading and Concurrency. I am currently trying to learn. I made a simple example to try to figure out how concurrency works.
Here is my code:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadedService {
private ExecutorService exec;
/**
* #param delegate
* #param poolSize
*/
public ThreadedService(int poolSize) {
if (poolSize < 1) {
this.exec = Executors.newCachedThreadPool();
} else {
this.exec = Executors.newFixedThreadPool(poolSize);
}
}
public void add(final String str) {
exec.execute(new Runnable() {
public void run() {
System.out.println(str);
}
});
}
public static void main(String args[]) {
ThreadedService t = new ThreadedService(25);
for (int i = 0; i < 100; i++) {
t.add("ADD: " + i);
}
}
}
What do I need to do to make the code print out the numbers 0-99 in sequential order?
Thread pools are usually used for operations which do not need synchronization or are highly parallel.
Printing the numbers 0-99 sequentially is not a concurrent problem and requires threads to be synchronized to avoid printing out of order.
I recommend taking a look at the Java concurrency lesson to get an idea of concurrency in Java.
The idea of threads is not to do things sequentially.
You will need some shared state to coordinate. In the example, adding instance fields to your outer class will work in this example. Remove the parameter from add. Add a lock object and a counter. Grab the lock, increment print the number, increment the number, release the number.
The simplest solution to your problem is to use a ThreadPool size of 1. However, this isn't really the kind of problem one would use threads to solve.
To expand, if you create your executor with:
this.exec = Executors.newSingleThreadExecutor();
then your threads will all be scheduled and executed in the order they were submitted for execution. There are a few scenarios where this is a logical thing to do, but in most cases Threads are the wrong tool to use to solve this problem.
This kind of thing makes sense to do when you need to execute the task in a different thread -- perhaps it takes a long time to execute and you don't want to block a GUI thread -- but you don't need or don't want the submitted tasks to run at the same time.
The problem is by definition not suited to threads. Threads are run independently and there isn't really a way to predict which thread is run first.
If you want to change your code to run sequentially, change add to:
public void add(final String str) {
System.out.println(str);
}
You are not using threads (not your own at least) and everything happens sequentially.

Categories

Resources