Sharing an ArrayList between two threads? - java

So I have two threads running where one of them is supposed to get information from the user and the other thread is suppose to work with information supplied by users as follows:
public class UserRequest implements Runnable {
#Override
public void run() {
// TODO Auto-generated method stub
String request;
Scanner input = new Scanner(System.in);
while(true)
{
System.out.println("Please enter request:");
request = input.nextLine();
try
{
//do something
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
And second thread:
public class Poller implements Runnable {
ArrayList<String> colors = new ArrayList<String>();
public void poll()
{
for(String color : colors)
{
if(color == "")
{
//do work
}
else
{
//do work
}
}
}
#Override
public void run() {
colors.add("Violet");
colors.add("Green");
colors.add("Yellow");
colors.add("Orange");
while(true)
poll();
}
}
What I would like to do is take whatever input the user entered inside the UserRequest object and push into the ArrayList in Poller object so it can "work" on the new value as well. I have looked at some thing like BlockingQueue but I don't want either Thread to wait for the other since they have other tasks they need to accomplish in addition to this sharing of data. How can I go about doing this ?

Since you've used the verb 'push' and 'poll', it seems you are looking for a Queue not a List.
Therefore, I think you're looking for the ConcurrentLinkedQueue, documented here.
It allows you to have your UserRequest objects feed it and your Poller objects to consume it.
Though it seems your Poller objects will have quite a high CPU consuption because of the open while not having any wait:
public class Poller implements Runnable {
Queue<String> colors = new ConcurrentLinkedQueue<String>();
public void poll() {
while(this.colors.isEmpty()){
Thread.currentThread().wait();
}
String color = this.colors.poll();
while(color != null) {
if(color == "") {
//do work
} else {
//do work
}
color = this.colors.poll();
}
}
#Override
public void run() {
colors.offer("Violet");
colors.offer("Green");
colors.offer("Yellow");
colors.offer("Orange");
while(true) {
this.poll();
}
}
}
this code needs some changes to run but it contains pretty much everything you need.
What it does is very simple: It keeps polling until there are no elements left.
Once that happens, the Poller object asks it's current Thread to sleep, since there's no point for it to run without elements in the Queue.
public class UserRequest implements Runnable {
#Override
public void run() {
String request;
Scanner input = new Scanner(System.in);
while(true) {
System.out.println("Please enter request:");
request = input.nextLine();
try {
//do something
} catch(IOException e) {
e.printStackTrace();
} finally {
this.notifyAll(); // Notifies all sleeping threads to wake up
}
}
}
If you notice, I've only added a notifyAll call to your UserRequest class. Why? Very simple: notifyAll wakes all waiting Threads which is exactly what all Pollers without elements are doing.
Once it's called, the Pollers will wake, check if their color Queue has elements and work with them. If the Queue has no elements, they will sleep again until a UserRequest wakes them up again and so on and so forth.

There are two ways to solve this problem:
1) It's using thread safe collection, like ConccurentLinkedQueue for logic with producer-consumer, jobs consuming or etc. If you want to use the class that implements List interface (and as a consequence you can take methods same to usual ArrayList), you must look to the side of CopyOnWriteArrayList, but note that this class uses blocking synchronization.
2) Another approach is using built-in java synchronization tools, for example
Semaphore
CyclicBarrier
CountDownLatch
Locks
Phaser
Usual wait/notify mechanism
For more details, you must read the specification. Let's consider an example of using Semaphore:
private final Semaphore semaphore = new Semaphore(2, true);
public void appendToList() throws InterruptedException {
available.acquire();
arrayList.add(.....); //put here what u need
}
public void putItem(Object x) {
if (someLogicHere(x)) //semaphore releases counter in this place
available.release();
}
Of course, you can combine usage all of them, e.g. you can use a few semaphores simultaneously, or use diff tools.

"but I don't want either Thread to wait for the other since they have other tasks they need to accomplish in addition to this sharing of data."
There's no way to accomplish this. Any proper threading of the class will always suffer from the problem that you will need to have one thread wait while the other does something. The point though is you want to minimize that. You want to only cause the thread to stall very briefly and rarely and only in those cases where not doing so will cause it to fault. You can use one of the synchronized data structures or you can just write a little bit of synchronization code yourself.
The only object in question is the arraylist, and you want the absolute minimum amount of stall on either thread. So you would want to synchronize it based on the object of the arraylist itself. So just write a couple little synchronization blocks around the points where you access the arraylist object.
public class Poller implements Runnable {
ArrayList<String> colors;
public Poller(ArrayList<String> colors) {
this.colors = colors;
//pass in colors object, if modified from the scanner side it must synchronize the block around the colors object too.
}
public void doWork(String color) {
//do work
}
public void addColor(String color) {
synchronized (colors) {
colors.add(color);
}
}
#Override
public void run() {
while (!Thread.interrupted())
if (!colors.isEmpty()) {
String color;
synchronized (colors) {
color = colors.remove(0);
}
doWork(color); //work done outside synch
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
The point is just never be removing or adding things to the list at the same time. You cannot loop over the list as a whole because if the work is done in-loop it's a problem and the size of the array might change so you don't know how bit it is. But, you can use an ArrayList for this, just synchronize the blocks of code where you change the datastructure and get the string out of that synchronized block and then do work on it. This way the only stall is the brief instant one thread is reading or writing and the other one needs to. Both of which are very fast operations.

If you want access new value entered by the user from poller object then:
As objects are stored in heap , instead of creating a new instance of arrayList in the Poller class you could just send a reference of list object from the UserRequest.So that when yu change add new value to arrayList in userRequest it will be reflected in arrayList being used by Poller.
For Example, You can do it this way:
public class UserRequest implements Runnable {
private ArrayList<String> arrayList = new ArrayList<String>();
#Override
public void run() {
// TODO Auto-generated method stub
String request;
Scanner input = new Scanner(System.in);
while(true)
{
System.out.println("Please enter request:");
request = input.nextLine();
try
{
Poller poller = new Poller(arrayList);
Thread t = new Thread(poller);
t.start();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
You can change your Poller class like this:
public class Poller implements Runnable {
private ArrayList arrayList = null;
Poller(ArrayList<String> arrayList){
this.arrayList = arrayList;
}
public void poll()
{
for(String color : arrayList)
{
if(color == "")
{
//do work
}
else
{
//do work
}
}
}
#Override
public void run() {
while(true){
poll();
}
}
But instead of calling pool in a infinity loop you should add a listener to your arrayList so that you call poll() only when a new value has been added to the List.
You can check out this link to know more about adding listener to a ArrayList: https://stackoverflow.com/a/16529462/7083385

You can use a queue. A queue has its own poll method. You could make it static but i doubt that is the best approach. Generally I use spring to instantiate the queue in some kind of wrapper class but it doesnt look like you are taking that route.

Related

What is the correct way to avoid an empty synchronized block?

Recently I've started looking into multithreading, and I have a question, perhaps more experienced ones could help.
My program creates two parallel threads, each of them prints counts from 0 to 19 (the NumbersPrinter class, which implements the Runnable interface).
class NumbersPrinter implements Runnable {
private Mediator mediator;
private String name;
private int makeActionOnCount;
public NumbersPrinter(Mediator mediator, String name, int makeActionOnCount) {
this.mediator = mediator;
this.name = name;
this.makeActionOnCount = makeActionOnCount;
}
#Override
public void run() {
for(int i = 0; i<20; i++){
try {
synchronized(this.mediator) {
if(this.mediator.actionInProgress.get()) {
System.out.println(name + " waits");
wait();
}
}
System.out.println(this.name + " says " + i);
Thread.sleep(500);
if(i == makeActionOnCount) {
synchronized(this.mediator) {
System.out.println(this.name + " asks Mediator to perform action...");
this.mediator.performAction();
this.mediator.notify();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
When one of the threads reaches a certain number (defined in the makeActionOnCount variable), it starts performing a certain action that stops the execution of the second counter. The action lasts 5 seconds and after that both counters continue to count.
The counters are interconnected through an instance of the Mediator class, the performAcyion() method also belongs to the instance of the Mediator class.
import java.util.concurrent.atomic.AtomicBoolean;
class Mediator {
public AtomicBoolean actionInProgress = new AtomicBoolean(false);
public Mediator() {
}
public void performAction() throws InterruptedException {
actionInProgress.set(true);
System.out.println("Action is being performed");
Thread.sleep(5000);
System.out.println("Action has been performed");
actionInProgress.set(false);
}
}
Here's the Main class:
class Main {
public static void main(String[] args) throws InterruptedException{
Mediator mediator = new Mediator();
NumbersPrinter data = new NumbersPrinter(mediator, "Data", 10);
NumbersPrinter lore = new NumbersPrinter(mediator, "Lore", 5);
Thread oneThread = new Thread(data);
Thread twoThread = new Thread(lore);
System.out.println("Program started");
oneThread.start();
twoThread.start();
oneThread.join();
twoThread.join();
System.out.println("Program ended");
}
The way the program is written now - works fine, but I don't quite understand what exactly should I write in the first synchronized block, because if you delete all content from it, the program still works, since the counter that does not execute the performAction() method stops 'cause the counter cannot access the monitor of the Mediator object 'cause it is busy with the parallel counter. AtomicBoolean variable and checking it also makes no sense.
In other words, I may not use the wait () and notify () constructs at all, as well as the value of the AtomicBoolean variable, and just check access to the Mediator object's monitor every new iteration using an empty synchronized block. But I've heard that an empty synchronized block is a bad practice.
I am asking for help on how to rewrite the program to use the synchronized block and the wait() and notify() methods correctly.
Maybe I'm syncing on the wrong object? How would you solve a similar problem?
Thanks in advance

Locking all the strings in a collection

I have a collection of strings which must be locked upon by a thread for computing some information. These strings are nothing but unique entities which must be handled by only one thread at a time. Any thread other than the current thread trying to acquire lock on any of these entities in the collection must wait for the current thread to complete its execution and release the lock on the collection. Two entirely different collection containing different strings can be worked upon by two different threads concurrently. I am stuck how to implement this. I tried googling. But all I found was how to lock a single string not many strings. Any idea would be helpful.
For example,
Thread one is working on apple, oranges and bananas.
Thread two wants to works on apple and peaches.
Thread two must wait until Thread one releases the lock.
Update:
Instead of looking upon the lock literally think of it as a permit to use the entity. For example, if you need to use apple, you must acquire permission. The thread must block until it gets permission for all the entities in its collection.
Let met put it in this way. Thread1 [apples, oranges, bananas] seeks permission to use the entities in the collection to a Manager. Lets assume the manager gave permission to Thread1. If another thread Thread2 [apples, peaches] seeks permission, the Manager should not give permission since permission for apples is already owned by Thread1 and Thread2 must be blocked. Once Thread1 tells the manager that it has completed its work, the Manager can give permission to Thread2. Meanwhile, if another thread Thread3 [guava, pineapple] seeks permission, the Manager should not block it and grant permission readily.
Instead of operating on many lock I would choose one synchronized storage of "locked" Strings.
That would hugely simplify synchronization.
Something like that:
private final Set<String> elementsInProgress = new HashSet<String>(); // not thread-safe, accessed only from blocks synchronized on it
public void process(Collection<String> input) throws InterruptedException {
for (String stringToProcess : input) {
synchronized (elementsInProgress) {
while (elementsInProgress.contains(stringToProcess)) {
elementsInProgress.wait();
}
elementsInProgress.add(stringToProcess);
}
doProcess(stringToProcess);
synchronized (elementsInProgress) {
elementsInProgress.remove(stringToProcess);
elementsInProgress.notifyAll();
}
}
}
private void doProcess(String s){/* ... */}
The code snippet is untested, btw )
How about starting with guava-libraries
import com.google.common.collect.Interners;
import com.google.common.collect.Interner;
Then create an an interner. Weak references are OK b/c it's the particular instance that holds the lock. You could use a ConcurrentMap (careful to use putIfAbsent) to do your interning, but...
Interner<String> namedLocks = Interners.newWeakInterner();
Then the client threads can simply use synchronized. I'm using Callable to represent the work.
public <T> void doWork(String name, Callable<T> work) {
synchronized(namedLocks.intern("name")) {
return work.call();
}
}
This will work if Thread 1 (apple, oranges, bananas) and Thread 2 (apple, peaches) can work on (for example) "oranges" and "peaches" concurrently. The 'work' variable in this case represents the work of 'oranges' independently.
If Thread 2 must wait until Thread 1 is done with all three items before starting any of its own, then it's a bit more complex but still manageable. The 'work' in this case represents 'apple+oranges+bananas'.
public <T> T doWork(List<String> names, Callable<T> work) {
// important to avoid deadlocks
names = new ArrayList<>(names);
Collections.sort(names);
return doWorkInternal(names.iterator());
}
private <T> T doWorkInternal(Iterator<String> names, Callable<T> work) {
if(names.hasNext()) {
synchronized(namedLocks.intern(names.next())) {
return doWorkInternal(names, work);
}
} else { // no more locks to acquire
return work.call();
}
}
In the above, you're acquiring each lock in sorted order (important for deadlock) as you recurse down the stack.
public class FruitRunnable implements Runnable {
// this is the actual lock
private static final Object lock = new Object();
// here we store which objects are currently used
private static final Set<String> usedObjects = new HashSet<String>();
// these are the objects a thread will need
private final String[] neededObjects;
public FruitRunnable(String... neededObjects) {
this.neededObjects = neededObjects;
}
#Override
public void run() {
acquireLock(neededObjects);
// between these two methods we can assure that there is
// no other thread working on our resources
work();
// important! release the resources afterwards!
releaseLock(neededObjects);
}
private void work() {
System.out.println("working: " + Arrays.toString(neededObjects));
try {
// work of 10 seconds
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void acquireLock(String[] fruits) {
// go into lock
synchronized (lock) {
// loop until we can acquire our resources
boolean success = false;
while (!success) {
success = true;
for (String s : fruits) {
if (usedObjects.contains(s)) {
// too bad this fruit is already in use
success = false;
}
}
// on success add all used fruits to the usedObjects Set and return
if (success) {
for (String s : fruits) {
usedObjects.add(s);
}
return;
}
// if we had no success we will wait until some other thread
// releases fruits
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private void releaseLock(String[] fruits) {
synchronized (lock) {
// release the fruits and notify the other threads to re-check
for (String s : fruits) {
usedObjects.remove(s);
}
lock.notifyAll();
}
}
public static void main(String[] args) throws InterruptedException {
// starting the threads from your example
new Thread(new FruitRunnable("apple", "oranges", "bananas")).start();
new Thread(new FruitRunnable("apple", "peaches")).start();
Thread.sleep(2000);
new Thread(new FruitRunnable("guava", "pineapple")).start();
}
}
Find some comments on how it works in code.

Producer-consumers(many). Consumers take and put into the shared queue

I made a producer-consumer program. It's just a program in core java without any GUI(Swing or SWT). It has one producer who put objects into the queue.
Also there is a few consumers who must add some staff(for example String) into Every object in that shared queue. So, every consumer must handle every object in a shared queue.
In this case - every BookShelf must have items from All consumers in "books" ArrayList. consumers.
Question: What condition should I use in consumers to finish their threads correctly?
Here are the code fragments of the program. Maybe I implemented it in wrong way.
Here is an object for the queue:
public class BookShelf {
private int id;
private String name;
private int height;
private int weigh;
List<String> books = Collections.synchronizedList(new ArrayList<String>());
public BookShelf(int id, String name) {
this.id = id;
this.name = name;
}
public void addBook(String book) {
books.add(book);
}
public boolean eq(String book) {
synchronized (books) {
for (String b: books) {
if (b.equalsIgnoreCase(book)) {
return true;
}
}
}
return false;
}
other setters and getters..
}
Here is the producer class:
public class Producer implements Runnable {
private BlockingQueue myQueue;
public Producer(BlockingQueue myQueue) {
this.myQueue = myQueue;
}
public void run() {
for(int i=0; i<7; i++){
try {
System.out.println("Produced: " + i);
BookShelf myBookShelf = new BookShelf(i, "book #" + i);
myQueue.put(myBookShelf);
} catch (InterruptedException ex) {
//Proper handle
}
}
}
}
Here is one of consumers class:
public class Consumer implements Runnable {
private BlockingQueue myQueue;
public Consumer(BlockingQueue myQueue) {
this.myQueue = myQueue; }
public void run() {
while(true){
try {
BookShelf tempBookShelf = (BookShelf) myQueue.take();
//eq() is my method to check if ArraList has a book.
if (tempBookShelf.eq("Abc book")) {
System.out.println("It already has book");
myQueue.put(tempBookShelf);
Thread.sleep(2000);
} else {
tempBookShelf.addBook("Abc book");
myQueue.put(tempBookShelf);
Thread.sleep(2000);
}
} catch (InterruptedException ex) {
//Proper handle
}
}
}
}
Here is main class:
public class ProducerConsumerTest {
public static void main(String[] args) {
BlockingQueue sharedQueue = new LinkedBlockingQueue();
Thread prodThread = new Thread(new Producer(sharedQueue));
Thread consThread = new Thread(new Consumer(sharedQueue));
Thread consThread2 = new Thread(new Consumer2(sharedQueue));
prodThread.start();
consThread.start();
consThread2.start();
}
}
Register each consumer with the producer. Each consumer has its own queue and the producer puts the object into all the queues. Each consumer then process on the same instance of the object.
public interface Consumer{
public void process(BookShelf bs);
}
public class Producer implements Runnable{
private final List<Consumer> consumers = new CopyOnWriteArrayList<Consumer>(); // thread safe but not efficient with lots of changes
public void register(Consumer c){
consumers.add(c); // thread safe
}
public void run(){
for(;;){
BookShelf bs = generateBookShelfByWhateverMeans();
for (Consumer c : consumers){
c.process(bs);
}
}
}
}
public class BookShelfConsumer implements Runnable, Consumer{
private final BlockingQueue<BookShelf> queue = new LinkedTransferQueue<BookShelf>(); // unbounded & thread safe
public void process(BookShelf bs){
queue.offer(bs); // non-blocking
}
public void run(){
for(;;){
BookShelf bs = queue.take(); // blocks until got object or interrupted
// catch InterruptedException
// do whatever this consumer is supposed to do with the object
}
}
}
I would try using SwingWorker instead. It has a done() method that is executed when it's finished. See this page for some code examples.
If it's not Swing you are using, there is a similar function in Swt called Jobs. Check this page for examples. It also has a done() method being executed when the job is done.
Also there is a few(N number) consumers who must add some staff(for example String) into Every object in that shared queue
I assume you mean every consumer must add their thing to every object which ever enters the queue. In that case, this is not a producer-consumer problem, this is more like an observer-observable problem. Basically, when a new BookShelf is created, that is the Observable. All of the Observers should be notified about the BookShelf and given the opportunity to add their own Book.
I recommend using a ConcurrentLinkedQueue in Bookshelf instead of a synchronized list - it's lock free (doesn't need to be synchronized) and will probably be more efficient.
To end your consumers, change their while(true) loops to while(!cancel) loops. Give each consumer a cancel boolean as an instance variable that initializes to false, and give them a cancel() method that sets cancel to true. Call cancel() on your consumers when you're done with them. If you will always be canceling all of your consumers at once (instead of selectively canceling some but not others), then you can use a static cancel instead of an instance cancel.

Java function ending after time has elapsed

Here's what I want to do. Given a function
public void foo() {
}
I would like to have it end after certain time has elapsed. That is, imagine this is some kind of random generator which has to produce random objects that satisfy some difficult constraints and hence it may or may not succeed under a given time allotment. That is, the function may actually be something like this
public void foo() {
//task1
while(fails) {
//...
}
//task2
while(fails2) {
//...
}
//more tasks may follow, which use the data from the previous tasks to further try to satisfy difficult conditions
}
That is simply just an example. But the point is that the function consists of many while loops, many test cases, and lots of heavy computation.
The goal: I want to be able to say "run foo() and if 4 seconds has elapsed and foo() is still not done, then stop foo() immediately."
What I have tried: I have tried to include conditions on just about every line of foo() to see how much time has elapsed and to return out of the function if the 4 seconds has passed. But given how complicated foo() is, this is clearly very difficult to do code wise because this requires testing the time on every single line of the function.
My thought logic: I think this should be possible because there are functions that do this sort of thing, that terminate code regardless of the state, such as System.exit(1). That is the idea. I'd like to be able to call, from the outside, to have this function foo() terminate.
// foo method and global variables used
private static ArrayList<Integer> foo() {
// info class
class Info {
public boolean run, completed;
public ArrayList<Integer> list;
}
// declare info object, list
final Info info = new Info();
final Object wait = new Object();
// run a new thread
Thread t = new Thread(
new Runnable() {
// run method
#Override
public void run() {
// setup run
info.run = true;
info.completed = false;
info.list = new ArrayList<>();
// loop to modify list. Don't put a big piece of code that will
// take a long time to execute in here.
while(info.run) {
// example of what you should be doing in here:
info.list.add(1);
// and if you are done modifying the list, use:
break;
}
// done modifying list
info.completed = true;
synchronized(wait) {
wait.notify();
}
}
}
);
t.start();
// wait for four seconds, then return list
try {
synchronized(wait) {
wait.wait(4000);
}
} catch (InterruptedException e) { e.printStackTrace(); }
info.run = false;
return info.completed ? info.list : null;
}
// main method
public static void main(String[] args) {
// get list
ArrayList<Integer> list = foo();
System.out.println("Done!");
}
What the foo() method does?
Begins to modify the list it will eventually return
If the time took modifying this list exceeds four seconds, it will stop modifying the list and return the list.
It will return null if the list was stopped early.
It now only uses local variables!
Nice bonus, it will immediately return the list the second modifying it is done.
Submit it as a runnable to an executor service and call get on the returned future with the desired timeout. Then in the catch block for the timeout exception you can cancel the future.
EDIT: Code sample
import com.google.common.base.Throwables;
import java.util.concurrent.*;
public class ExecutorExample {
private static final ExecutorService executor = Executors.newSingleThreadExecutor();
public void example() {
Future<String> future = executor.submit(new Callable<String>() {
#Override
public String call() throws Exception {
return "Do your complicated stuff";
}
});
try {
future.get(4, TimeUnit.SECONDS);
} catch (InterruptedException e) {
Throwables.propagate(e);
} catch (ExecutionException e) {
//handle
} catch (TimeoutException e) {
future.cancel(true);
}
}
}
Something like this will do the trick, but beware:
public static void main(String[] args){
Runnable fooRunner = new Runnable(){ public void run(){
foo();
}
Thread fooThread = new Thread(fooRunner);
fooThread.start();
Thread.sleep(4000);
fooThread.stop(); //warning -- this is deprecated!
}
The problem is that Thread.stop is deprecated.
Multi-threading in Java is fundamentally a cooperative endeavor. Because foo() may be manipulating shared state, probably protected by a lock that it currently owns, stopping it at an arbitrary point is potentially very dangerous and could lead to unpredictable failures, bugs, etc. later on in the program. (Indeed, since foo's return type is void, it must manipulate some shared state at some point in order to store its result.)
The language does provide a way to tell a thread that it should stop at the next convenient point: Thread.interrupt(), Thread.interrupted(), and InterruptedException. Your foo() method does need to check whether it's been interrupted periodically; that's the way it's done, and any higher-level library constructs (like Future.cancel()) rely on this.
You must enter into the hellish arena of writing threaded code.
http://docs.oracle.com/javase/tutorial/essential/concurrency/
Pseudo code (mutableboolean available in apache commons http://commons.apache.org/lang/download_lang.cgi)
...
final MutableBoolean finished = new MutableBoolean(false);
new Thread(new Runnable(){
public void run() {
doComplicatedStuff(finished);
}
}).start();
Thread.sleep(4000);
finished.setValue(true);

can i know the Thread runnable class attributes in java?

probability this question have been asked before but i cant find anything in my searching mechanism. I am trying to create a multiple threads, in an array list but i want to retrieve them from an arraylist and filter them by the attribute of w1 i used in my code. any ideas ?
w1 = new FirstWorker(ProductsList, OrdersList, s);
FirstWorkerThread = new Thread(w1);
ThreadArrayList.add(FirstWorkerThread);
//I know i cant do the code below but i want to do that how ?
for(Thread x : ThreadArrayList){
x.ProductsList
}
this is FirstWorker class
import java.lang.String;
import java.util.HashMap;
/*
* To change this template, choose Tools | Templates and open the template in
* the editor.
*/
/**
*
* #author Dimitris
*/
public class FirstWorker extends Thread implements Runnable {
private OrderList orderlist;
private ProductList productlist;
private String Worker;
boolean Stop;
private int speed = 1000;
public FirstWorker(ProductList productlist, OrderList orderlist, String Worker) {
this.productlist = productlist;
this.orderlist = orderlist;
this.Worker = Worker;
this.Stop = true;
}
public void run() {
if (Stop == true) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
while (orderlist.returnLengthofOrder() != 0) {
if (Thread.interrupted()) {
System.out.println("I am in the thread inturrupt");
// We've been interrupted: no more crunching.
return;
}
if (orderlist.getDone() == true) {
} else if (orderlist.getDone() == false) {
orderlist.setDoneTrue();
orderlist.Purchased(Worker);
orderlist.setDoneFalse();
try {
Thread.sleep(this.speed);
} catch (InterruptedException e) {
return;
}
}
}
}
}
public void setWork() {
Stop = false;
}
public void setSpeed(int speed) {
this.speed = speed;
}
}
If you want to access a member variable of your Runnable, you should extend Thread instead of implementing Runnable. Also, don't extend Thread AND implement Runnable. Pick one.
public class MyThread extends Thread
{
public int myarg;
public void run()
{
}
}
public void useThread(int inputArgs[])
{
ArrayList<MyThread> threadArray = new ArrayList<MyThread>();
for (int arg : inputArgs)
{
MyThread temp = new MyThread(arg);
temp.start();
threadArray.add(temp);
}
for (MyThread t : threadArray)
System.out.println(t.myarg);
}
The simple answer with constructing a Thread with a Runnable is no.
The constructor for Thread that you are using accepts a Runnable ... I assume that FirstWorker implements the Runnable interface.
But looking at the API docs for Thread http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html there is no method to return the Runnable.
Without knowing more context about what your trying to do, the simplest approach might be to change FirstWorker to extend Thread then the loop you have would work.
That would probably work, but would need to know more about what your doing to reccomend anything else.
If you want to retrieve properties from the Runnable instance within a Thread object, I do not believe that is generally possible, since the Thread class does not have a method to return its target Runnable object.
That said, you can always extend the Thread class itself, which would allow you to use instanceof with the Thread instances themselves before casting and getting to whatever property you need.
Keep in mind, though, that extending Thread is not a recommended practice and if you are intending to get the result of some computation straight from the Runnable object, you could run into some severe trouble if you are not careful.
In any case, recent Java versions (i.e. 1.5+) offer substantial capabilities for concurrency and I suspect that your application would benefit from a re-design that uses them.
We might be able to help more if you explained what exactly you are trying to do in broader terms...
You should consider using the new java.util.concurrent package. What you are trying to do can be implemented a lot easier and intuitively with an ExecutorService and a collection of Callables.
Check out this sample and the Executors API (specifically the fixedThreadPool).

Categories