Access outer variable from inner anonymous Runnable - java

The following example code (SSCCE) complains that local variable a must be final.
public class Foo {
final List<A> list = new ArrayList() {{ add(new A()); }};
void foo() {
A a;
Thread t = new Thread(new Runnable() {
public void run() {
a = list.get(0); // not good !
}
});
t.start();
t.join(0);
System.out.println(a);
}
class A {}
}
To make things working i change the code to that one
public class Foo {
final List<A> list = new ArrayList() {{ add(new A()); }};
void foo() {
// A a;
final ObjectRef x = new ObjectRef();
Thread t = new Thread(new Runnable() {
public void run() {
// a = list.get(0);
x.set(list.get(0));
}
});
t.start();
t.join(0);
// System.out.println(a);
System.out.println(x.get());
}
class A {}
class ObjectRef<T> {
T x;
public ObjectRef() {}
public ObjectRef(T x) { this.x = x; }
public void set(T x) { this.x = x; }
public T get() { return x; }
}
}
My questions:
Is there something wrong with this ?
The ObjectRef class exists as standard class in JSE ?
What is the right way ?

Right way is using FutureTask and Callable
FutureTask task = new FutureTask(new Callable<A>() {
public A call() {
return list.get(0);
}
});
Executor ex = Executors.newFixedThreadPool(1);
ex.execute(task);
// do something else, code is executing in different thread
A a = task.get(); //get result of execution, will wait if it's not finished yet
ex.shutdown();

Did you consider using Callable instead? Callable can be used when you produce a result, which seem to be your case.
final List<A> list = new ArrayList() {{ add(new A()); }};
void foo() {
Callable<A> call = new Callable<A> {
A call() throws Exception
{
// do something with the list
return list.get(0);
}
}
ExecutorService executor = new ScheduledThreadPoolExecutor(1);
Future<A> future = executor.submit(call);
System.out.println( future.get() );
}

I agree that you should go with Callable and FutureTask.
But it may not be necessary to use an Executor: If you are not going to share that Executor with other code, the three lines required to create it, submit the task, and then shut it down again, seem too verbose. You could just use a Thread.
FutureTask<A> task = new FutureTask(new Callable<A>() {
public A call() {
return list.get(0);
}
});
new Thread(task).start();
A result = task.get();

Related

Java FixedThreadPool with resources per thread?

This is a pseudocode version of my current working code:
public class DataTransformer {
private final boolean async = true;
private final ExecutorService executorService = Executors.newSingleThreadExecutor();
public void modifyAsync(Data data) {
if (async) {
executorService.submit(new Runnable() {
#Override
public void run() {
modify(data);
}
});
} else {
modify(data);
}
}
// This should actually be a variable inside modify(byte[] data)
// But I reuse it to avoid reallocation
// This is no problem in this case
// Because whether or not async is true, only one thread is used
private final byte[] temp = new byte[1024];
private void modify(Data data) {
// Do work using temp
data.setReady(true); // Sets a volatile flag
}
}
Please read the comments. But now I want to use Executors.newFixedThreadPool(10) instead of Executors.newSingleThreadExecutor(). This is easily possible in my case by moving the field temp inside modify(Data data), such that each execution has it's own temp array. But that's not what I want to do because i want to reuse the array if possible. Instead I want for each of the 10 threads a temp array. What's the best way to achieve this?
As static variable is shared between all Threads, so you could declare as static. But if you want to use different values then either use Threadlocal or use different object.
With ThreadLocal you could do :
ThreadLocal<byte[]> value = ThreadLocal.withInitial(() -> new byte[1024]);
You could also use object like this:
public class Test {
public static void main(String[] args) {
try {
Test test = new Test();
test.test();
} catch (Exception e) {
e.printStackTrace();
}
}
class Control {
public volatile byte[] temp = "Hello World".getBytes();
}
final Control control = new Control();
class T1 implements Runnable {
#Override
public void run() {
String a = Arrays.toString(control.temp);
System.out.println(a);
}
}
class T2 implements Runnable {
#Override
public void run() {
String a = Arrays.toString(control.temp);
System.out.println(a);
}
}
private void test() {
T1 t1 = new T1();
T2 t2 = new T2();
new Thread(t1).start();
new Thread(t2).start();
}
}

ExecutorService thread safety

Let's say I have an instance of ExecutorService from one of Executors static factory methods.
If I submit a Callable where RetVal is not a thread-safe, locally instantiated object from some thread, do I need to worry about RetVals' integrity when I get() it from the same thread? People say that local variables are thread-safe, but I am not sure if it applies when you're returning a locally instantiated Object and receiving it from some other thread.
Here's an example similar to my situation:
ExecutorService executor = Executors.newFixedThreadPool(5);
Future<List<String>> fut = executor.submit(() -> {
List<String> ret = new ArrayList<>();
ret.add("aasdf");
ret.add("dfls");
return ret;
});
List<String> myList = fut.get();
In the above example, I'm retrieving an ArrayList that was created in a different thread--one created by executor. I don't think above code is thread safe but I was not able to find much information regarding my specific situation.
Now I tried the above code on my computer and it actually returned the expected result 100% of the time I tried it, and I even tried with my own implementation of an ExecutorService and so far I have only got the expected results. So unless I have gotten extremely lucky I am pretty sure it works but I'm not sure how.
I created a not thread-safe object in another thread and received it in another; shouldn't I have a chance to have received a partially constructed object--in my case a list that does not contain 2 strings?
Below is my custom implementation I made just to test. You can ignore the EType enum thingy.
class MyExecutor {
enum EType {
NoHolder, Holder1, Holder2
}
private ConcurrentLinkedQueue<MyFutureTask<?>> tasksQ;
private final Thread thread;
private final EType eType;
public MyExecutor(EType eType) {
eType = Objects.requireNonNull(eType);
tasksQ = new ConcurrentLinkedQueue<>();
thread = new Thread(new MyRunnable());
thread.start();
}
public <T> Future<T> submit(Callable<T> c) {
MyFutureTask<T> task = new MyFutureTask<T>(c, eType);
tasksQ.add(task);
return task;
}
class MyRunnable implements Runnable {
#Override
public void run() {
while (true) {
if (tasksQ.isEmpty()) {
try {
Thread.sleep(1);
continue;
} catch (InterruptedException ite) {
Thread.interrupted();
break;
}
}
MyFutureTask<?> task = tasksQ.poll();
try {
task.run();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
class MyFutureTask<T> implements RunnableFuture<T> {
final Callable<?> cb;
volatile Object outcome;
static final int STATE_PENDING = 1;
static final int STATE_EXECUTING = 2;
static final int STATE_DONE = 3;
final AtomicInteger atomicState = new AtomicInteger(STATE_PENDING);
final EType eType;
public MyFutureTask(Callable<?> cb, EType eType) {
cb = Objects.requireNonNull(cb);
eType = Objects.requireNonNull(eType);
}
#Override
public boolean cancel(boolean mayInterruptIfRunning) {
throw new NotImplementedException();
}
#Override
public boolean isCancelled() {
return false;
}
#Override
public boolean isDone() {
return atomicState.get() == STATE_DONE;
}
#SuppressWarnings("unchecked")
#Override
public T get() throws InterruptedException, ExecutionException {
while (true) {
switch (atomicState.get()) {
case STATE_PENDING:
case STATE_EXECUTING:
// Thread.sleep(1);
break;
case STATE_DONE:
return (T)outcome;
default:
throw new IllegalStateException();
}
}
}
#Override
public T get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
throw new NotImplementedException();
}
void set(T t) {
outcome = t;
}
#Override
public void run() {
if (atomicState.compareAndSet(STATE_PENDING, STATE_EXECUTING)) {
Object result;
try {
switch (eType) {
case NoHolder:
result = cb.call();
break;
case Holder1:
throw new NotImplementedException();
case Holder2:
throw new NotImplementedException();
default:
throw new IllegalStateException();
}
} catch (Exception e) {
e.printStackTrace();
result = null;
}
outcome = result;
atomicState.set(STATE_DONE);
}
}
}
}
class MyTask implements Callable<List<Integer>> {
#Override
public List<Integer> call() throws Exception {
List<Integer> ret = new ArrayList<>(100);
IntStream.range(0, 100).boxed().forEach(ret::add);
return ret;
}
}
The important thing is the happens-before relationship. From ExecutorService API docs:
Memory consistency effects: Actions in a thread prior to the
submission of a Runnable or Callable task to an ExecutorService
happen-before any actions taken by that task, which in turn
happen-before the result is retrieved via Future.get().
So you are safe to transfer a mutable object like this. The ExecutorService implementation transfers the object via some form of safe publication.
Obviously, don't update the object in the original thread after returning it.
If you were to communicate between threads by stashing in a shared non-volatile field, then that would be unsafe.
Thread safety becomes a concern when multiple threads try to access and modify the same state simultaneously.
Note that you will not get hold of the actual result from a Future until the task is finished (i.e. Future#get will not return until the task is finished).
In your first example, thread safety is not an issue because the a new object (while mutable) is created by one thread (the thread created by the Executor) and retrieved from the Future object once that thread has finished processing the task. Once the calling thread gets hold of the object, it cannot be modified by any other thread, because the creating thread no longer has access to the List.

How to get the output stream from a thread

I currently have several runnable classes, each printing a string upon completion using System.out.println().
In the main() I execute them using a ExecutorService ,executor.execute() for each of them.
I am wondering after executing those threads, how to get the output stream from them for future use ?
Pretty much like using .getInputStream for processes but there's no such method in the Thread class. Thanks!
There's a class which implements runnable interface like this:
public class A implements Runnable {
public void run() {
System.out.println(5); //this thread always print out number 5
}
}
and in the main function I need to get the printed number and store it
public static void main(String[] args) {
ExecutorService ThreadPool = Executors.newFixedThreadPool(1);
ThreadPool.execute(new A()); //This statement will cause the thread object A
//to print out number 5 on the screen
ThreadPool.shutdown();
......
}
Now I need to get the printed number 5 and store it into, say an integer variable.
I think below code will satisfy your requirement.
class MyCallable implements Callable<InputStream>
{
#Override
public InputStream call() throws Exception {
//InputStream inputStreamObject = create object for InputStream
return inputStreamObject;
}
}
class Main
{
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);
List<Future<InputStream>> list = new ArrayList<Future<InputStream>>();
for (int i = 0; i < 25; i++) {
Callable<InputStream> worker = new MyCallable();
Future<InputStream> submit = executor.submit(worker);
list.add(submit);
}
InputStream inputStreamObject = null;
for (Future<InputStream> future : list) {
try {
inputStreamObject = future.get();
//use inputStreamObject as your needs
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
executor.shutdown();
}
}
Runnable and Callable in thread:
runnable interface has a method public abstract void run(); void - which means after completing run method, it will not return anything. Callable<V> interface has a method V call() throws Exception; which means after completing call method, it will return Object V that is parametrized as
public class Run_Vs_Call {
public static void main(String...args){
CallableTask call = new CallableTask();
RunnableTask run = new RunnableTask();
try{
FutureTask<String> callTask = new FutureTask<String>(call);
Thread runTask = new Thread(run);
callTask.run();
runTask.start();
System.out.println(callTask.get());
}catch(Exception e){
e.printStackTrace();
}
}
public static class CallableTask implements Callable<String>{
public String call( ){
String stringObject = "Inside call method..!! I am returning this string";
System.out.println(stringObject);
return stringObject;
}
}
public static class RunnableTask implements Runnable{
public void run(){
String stringObject = "Inside Run Method, I can not return any thing";
System.out.println(stringObject);
}
}
}
you can use new static class:
public class Global{
//example
public static ..
public static ..
}

How to synchronize two methods

I have following code for a chat server application in Java -
public synchronized List<ChatMessage> getMessages(int messageNumber) {
return messages.subList(messageNumber + 1, messages.size());
}
public synchronized int addMessage(ChatMessage c) {
messages.add(c);
return messages.size()-1;
}
I have following test code -
public static void main(String[] args) {
final ChatRoom c = new ChatRoom();
Thread user1 = new Thread(new Runnable() {
public void run() {
for(int i=0;i<1000;i++) {
c.addMessage(new ChatMessage());
c.getMessages(0);
}
}
});
Thread user2 = new Thread(new Runnable() {
public void run() {
for(int i=0;i<1000;i++) {
c.addMessage(new ChatMessage());
c.getMessages(0).size();
}
}
});
user1.start();
user2.start();
}
I am getting a ConcurrentModificationException.
How is this possible?
How is this possible?
Your getMessages method just returns a view on the original list. It doesn't create a copy of the list. So one thread is using a view on the list while another modifies the list - at that point, you get the exception.
From the docs for List.subList:
The semantics of the list returned by this method become undefined if the backing list (i.e., this list) is structurally modified in any way other than via the returned list. (Structural modifications are those that change the size of this list, or otherwise perturb it in such a fashion that iterations in progress may yield incorrect results.)
It's not clear what you're really trying to achieve here, but fundamentally you can't use subList to magically create a thread-safe list :)
The simplest thing to do is to create a combined method
public synchronized int addMessageAndGetCount(ChatMessage c) {
messages.add(c);
return messages.size();
}
public static void main(String... args) {
final ChatRoom c = new ChatRoom();
final Runnable runner = new Runnable() {
public void run() {
for(int i = 0; i < 1000; i++) {
c.addMessageAndGetCount(new ChatMessage());
}
}
};
new Thread(runner).start();
new Thread(runner).start();
}
You cannot safely return a list or a subList from a synchronized block. You can return a copy but all you need is the size.

Am I using callable and futures multithreading the right way (java)?

I need some tasks to be done multi threaded.
I know in advance that i will continue with my program when all tasks are completed.
Is the following code right for this purpose?
public void test() {
Callable<String> myCall = new Callable() {
#Override
public String call() throws Exception {
return doDomething();
}
};
Callable<String> myCall2 = new Callable() {
#Override
public String call() throws Exception {
return doDomething2();
}
};
ExecutorService executor = Executors.newFixedThreadPool(2);
List<Callable<String>> list = Arrays.asList(myCall,myCall2);
List<Future<String>> futuresList = executor.invokeAll(list);
String result1 = futuresList.get(0).get();
String result2 = futuresList.get(0).get();
//...
}
I'm trying to change this to work with generics:
public void test() {
Callable<?> myCall = new Callable() {
#Override
public String call() throws Exception {
return doDomething();
}
};
Callable<?> myCall2 = new Callable() {
#Override
public String call() throws Exception {
return doDomething2();
}
};
ExecutorService executor = Executors.newFixedThreadPool(2);
List<Callable<?>> list = Arrays.asList(myCall,myCall2);
List<Future<?>> futuresList = executor.invokeAll((Collection<? extends Callable<?>>)list);
String result1 = futuresList.get(0).get();
String result2 = futuresList.get(0).get();
// ...
}
I get the following compilation error:
The method invokeAll(Collection<? extends Callable<T>>) in the type ExecutorService is not applicable for the arguments (Collection<capture#2-of ? extends Callable<?>>).
Aside from you accessing the zeroth index twice I dont see anything wrong with it.
This edit is in regards to your question on how to implement it without the ExecutorService. As ColinD notes, you really shouldn't I will show why
To get the same set of functionality you would need two Objects and use two threads as a latch
String result1 = null;
String result2 = null;
public void test() {
Thread thread1 = new Thread(new Runnable(){
public void run(){
result1 = doSomething();
}
});
Thread thread2 = new Thread(new Runnable(){
public void run(){
result2 = doSomething2();
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
...
...
}
Now what if you want to add another thread/unit-of-work then you need
Thread thread3 = new Thread(new Runnable(){
public void run(){
result3 = doSomething3();
}
});
thread3.start();
thread3.join();
And so forth. Hence your solution is the better way to do this.
Well, let me be devil's advocate then.
The only thing in this example that actually can hit right back at you is the fact that you are calling two methods a-sychronously which is probably not that obvious to other programmers.
I guess this is just an example, but other programmers might not recognize that doSomething and doSomething2 should not have 'shared mutable state' since they are executed a-synchronously. It's not that obvious in this setup.
So I would recommend to actually put the logic in separate classes.

Categories

Resources