Java Runnable without static reference - java

I am trying to learn multi-threading using the runnable interface but I am having some trouble figuring out how to pass information. Basically, in the example below, I want to remove the static reference from the Hashmap but if I do that, the program breaks. How do I pass the hashmap to the runnable interface class without using the static keyword?
public class ThreadDemo {
static HashMap <String, Integer>map = new HashMap<>();
public String Hi() {
return "hi";
}
public String Hello() {
return "Hello";
}
public void addToMap(String item) {
if (map.containsKey(item)) {
map.put(item, map.get(item) + 1);
} else {
map.put(item, 1);
}
}
public static void main(String[] args) throws InterruptedException {
ArrayList<Thread> all = new ArrayList<>();
for (int i = 0; i < 50; ++i) {
threader threader = new threader();
all.add(new Thread(threader));
}
for (Thread thread : all) {
thread.start();
}
for (Thread thread : all) {
thread.join();
}
ThreadDemo td = new ThreadDemo();
System.out.println(td.map);
}
}
And a class that implements Runnable
public class threader implements Runnable {
ThreadDemo td = new ThreadDemo();
#Override
public void run() {
synchronized(td.map) {
td.addToMap(td.Hi());
td.addToMap(td.Hello());
}
}
}

A class instance is all about information.
public class threader implements Runnable {
final private ThreadDemo td;
public threader(ThreadDemo td) {
this.td = td;
}
#Override
public void run() {
..
}
}
then to use (details omitted, just the idea):
ThreadDemo theTd = new ThreadDemo();
for (...) {
threader threader = new threader(theTd);
all.add(new Thread(threader));
}
....
Of course, all threads are using the same ThreadDemo, with the same map, so you'll need to ensure access is interlocked in some way, e.g., by using synchronized. The ThreadDemo.addToMap method should be synchronized in this example, rather than the caller of addToMap. This puts the responsibility for the "care of the map" into the place that actually owns the map, and is consequently a better design.
I chose to share the ThreadDemo rather than just the map inside the ThreadDemo, since it looks to me that the intent of ThreadDemo is just to be a wrapper around the map.

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

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 switch between two thread back and forth

I have two methods in two different classes, like this
public class ClassX implements Runnable {
public void methodAandB() {
for(int i=0;i<10;i++) {
System.out.println("This is A and B ");
}
}
#Override
public void run() {
methodAandB();
}
}
public class ClassY implements Runnable {
public void methodAorB() {
for(int i=0;i<10;i++) {
System.out.println("This is A or B");
}
}
#Override
public void run() {
methodAorB(a);
}
}
Thread t1 is calling methodAandB().
Thread t2 is calling methodAorB().
Can I switch between these two threads after each iteration of loop in methods?
I want to get output like this:
This is A and B
This is A or B
This is A and B
This is A or B
This is A and B
This is A or B
This is A and B
This is A or B
Best example of flip-flop between threads:
Given two int array (even and odd), 2 threads printing their numbers in natural order.
package com.rough;
public class ThreadsBehaviour {
static Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
int a[] = {1,3,5,7,9};
int b[] = {2,4,6,8,10};
Thread odd = new Thread(new Looper(a, lock));
Thread even = new Thread(new Looper(b, lock));
odd.start();
even.start();
}
}
class Looper implements Runnable
{
int a[];
Object lock;
public Looper(int a[], Object lock)
{
this.a = a;
this.lock = lock;
}
#Override
public void run() {
for(int i = 0; i < a.length; i++)
{
synchronized(lock)
{
System.out.print(a[i]);
try
{
lock.notify();
if(i == (a.length - 1))
{
break;
}
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
You can achieve this simply by using the shared variables. I have implemented and verified the problem. code is below
class X
public class ClassX implements Runnable {
public void methodAandB() {
for(int i=0;i<10;i++) {
while(GlobalClass.isClassXdone)
{}
System.out.println("This is A and B ");
GlobalClass.isClassXdone = true;
GlobalClass.isClassYdone = false;
}}
#Override
public void run() {
methodAandB(); } }
ClassY
public class ClassY implements Runnable {
public void methodAorB() {
for(int i=0;i<10;i++) {
while(GlobalClass.isClassYdone)
{}
System.out.println("This is A or B ");
GlobalClass.isClassYdone = true;
GlobalClass.isClassXdone = false;}}
#Override
public void run() {
methodAorB();}}
Definition of the shared variable
public class GlobalClass {
public static boolean isClassXdone = false ;
public static boolean isClassYdone = false ;
}
You can just start your thread using t1.start and t2.start to get the desired output
Thread t1 = new Thread(new ClassX());
Thread t2 = new Thread(new ClassY());
t1.start();
t2.start();
This is probably more than needed to solve the problem, but, as it seems to be an introduction to concurrent programming exercise, it should be along the lines of what you'll encounter.
You should probably have a shared object that both your threads know, so that they may synchronize through it. Like so:
public class MyMutex {
private int whoGoes;
private int howMany;
public MyMutex(int first, int max) {
whoGoes = first;
howMany = max;
}
public synchronized int getWhoGoes() { return whoGoes; }
public synchronized void switchTurns() {
whoGoes = (whoGoes + 1) % howMany;
notifyAll();
}
public synchronized void waitForMyTurn(int id) throws
InterruptedException {
while (whoGoes != id) { wait(); }
}
}
Now, your classes should receive their respective identifier, and this shared object.
public class ClassX implements Runnable {
private final int MY_ID;
private final MyMutex MUTEX;
public ClassX(int id, MyMutex mutex) {
MY_ID = id;
MUTEX = mutex;
}
public void methodAandB() {
for(int i = 0; i < 10; i++) {
try {
MUTEX.waitForMyTurn(MY_ID);
System.out.println("This is A and B ");
MUTEX.switchTurns();
} catch (InterruptedException ex) {
// Handle it...
}
}
}
#Override
public void run() { methodAandB(); }
}
ClassY should do the same. Wait for its turn, do its action, and then yield the turn to the other.
I know it's a little late to answer this. But it's yesterday only I have come across this question. So I guess it's never too late.. ;)
Solution, as #afsantos mentioned is having a shared object between the two threads and implementing mutual exclusion on the shared object. The shared object could be alternatively locked by the two threads. Two possible implementations are as follows. This is actually more like an extension of #afsantos solution. His work is hereby acknowledged.
Solution 1:
Blueprint of the object that will be shared is as follows.
public class MutEx {
public int whoGoes, howMany;
public MutEx(int whoGoes, int howMany) {
this.whoGoes = whoGoes;
this.howMany = howMany;
}
public synchronized void switchTurns(){
this.whoGoes = (this.whoGoes + 1) % 2;
notifyAll();
}
public synchronized void waitForTurn(int id) throws InterruptedException{
while(this.whoGoes != id)
wait();
}
}
Then, you could implement the ClassX as follows.
public class ClassX implements Runnable {
private final int MY_ID;
private final MutEx MUT_EX;
public ThreadOne(int MY_ID, MutEx MUT_EX) {
this.MY_ID = MY_ID;
this.MUT_EX = MUT_EX;
}
#Override
public void run(){
this.doTheWork();
}
public void doTheWork(){
for(int i = 0; i < 10; i++){
try {
MUT_EX.waitForMyTurn(MY_ID);
System.out.println("This is A and B");
MUT_EX.switchTurns();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
ClassY also will be the same, with whatever the differences you need to be there. Then, in the invocation (i.e. in the main method),
public static void main(String[] args) {
MutEx mutEx = new MutEx(0, 2);
Thread t1 = new Thread(new ClassX(0, mutEx);
Thread t2 = new Thread(new ClassY(1, mutEx));
t1.start();
t2.start();
}
Voila! You have two threads, alternating between each as you need.
Solution 2: Alternatively, you could implement the ClassX & ClassY as follows.
public class ClassX extends Thread{
Here, you are subclassing the java.lang.Thread to implement your requirement. For this to be invoked, change the main method as follows.
public static void main(String[] args) {
MutEx mutEx = new MutEx(0, 2);
ClassX t1 = new ClassX(0, mutEx);
ClassY t2 = new ClassY(1, mutEx);
t1.start();
t2.start();
}
Run this, and you have the same result.
If you don't need to use Thread try this code:
for (int i = 0; i < 20; i++) {
if (i % 2 == 0) {
methodAandB();
} else {
methodAorB();
}
}

Passing an argument to a method defined inside a method in Java

So the situation is something like this:
private void myMethod()
{
System.out.println("Hello World"); //some code
System.out.println("Some Other Stuff");
System.out.println("Hello World"); //the same code.
}
We don't want to be repeating our code.
The technique described here works pretty well:
private void myMethod()
{
final Runnable innerMethod = new Runnable()
{
public void run()
{
System.out.println("Hello World");
}
};
innerMethod.run();
System.out.println("Some other stuff");
innerMethod.run();
}
But what if I want to pass in a parameter to that inner method?
eg.
private void myMethod()
{
final Runnable innerMethod = new Runnable()
{
public void run(int value)
{
System.out.println("Hello World" + Integer.toString(value));
}
};
innerMethod.run(1);
System.out.println("Some other stuff");
innerMethod.run(2);
}
gives me: The type new Runnable(){} must implement the inherited abstract method Runnable.run()
While
private void myMethod()
{
final Runnable innerMethod = new Runnable()
{
public void run()
{
//do nothing
}
public void run(int value)
{
System.out.println("Hello World" + Integer.toString(value));
}
};
innerMethod.run(1);
System.out.println("Some other stuff");
innerMethod.run(2);
}
gives me The method run() in the type Runnable is not applicable for the arguments (int).
Nope, that isn't a method but an anonymous object. You can create an extra method to use for the object.
Thread thread = new Thread( new Runnable()
{
int i,j;
public void init(int i, int j)
{
this.i = i;
this.j=j;
}
});
thread.init(2,3);
thread.start();
And wrap runnable in a Thread, and call start! Not run().
Because you can't call the constructor of an anonymous class, as pointed out by #HoverCraft you could extend a named class that implements Runnable.
public class SomeClass implements Runnable
{
public SomeClass(int i){ }
}
Looks like you just want inner methods. Java does't let you have them, so the Runnable hack you describe lets you sort-of declare an inner method.
But since you want more control over it, why not define your own:
interface Inner<A, B> {
public B apply(A a);
}
Then you can say:
private void myMethod(..){
final Inner<Integer, Integer> inner = new Inner<Integer, Integer>() {
public Integer apply(Integer i) {
// whatever you want
}
};
// then go:
inner.apply(1);
inner.apply(2);
}
Or use some library that provides functor objects. There should be many. Apache Commons has a Functor that you can use.

Threads calling both static and non-static method

Disclaimer: This code is copied from synchronized blocks for static and non-static methods
I made some modification to it. I want to know how to make threads call both synchronized static and non-static methods. I can make it work by wrapping the non-static method in a synchronized block. Is there any other way?
public class StaticNonStaticSynch
{
public static void main(String[] args)
{
final StaticNonStaticTest staticNonStaticTest = new StaticNonStaticTest();
Runnable runnable1 = new Runnable()
{
#Override
public void run()
{
staticNonStaticTest.nonStaticMethod();
}
};
Runnable runnable2 = new Runnable()
{
#Override
public void run()
{
StaticNonStaticTest.staticMethod();
}
};
Thread thread1 = new Thread(runnable1, "First Thread");
Thread thread2 = new Thread(runnable2, "Second Thread");
thread1.start();
thread2.start();
}
}
class StaticNonStaticTest
{
void nonStaticMethod()
{
//synchronized (StaticNonStaticTest.class){
for(int i=0;i<50;i++)
{
System.out.println("Non - Static method called by " + Thread.currentThread().getName() +" : = "+i);
}
// }
}
static synchronized void staticMethod()
{
for(int i=0;i<50;i++)
{
System.out.println("Static method called by " + Thread.currentThread().getName() +" : = "+i);
}
}
}
Remember that this:
public class MyClass {
public synchronized void doSomething() {
// Do something
}
public synchronized static void doSomethingStatic() {
// Do something static
}
}
Essentially compiles to this:
public class MyClass {
public void doSomething() {
synchronized(this) {
// Do something
}
}
public static void doSomethingStatic() {
synchronized(MyClass.class) {
// Do something static
}
}
}
Notice that they don't synchronize on the same thing. To fix this, create an object for both of them to lock on (known as a mutually exclusive object, or a "mutex"):
public class MyClass {
private static final Object MUTEX = new Object();
public void doSomething() {
synchronized(MUTEX) {
// Do something
}
}
public static void doSomethingStatic() {
synchronized(MUTEX) {
// Do something static
}
}
}
That should make it so that only one of these two methods are running at the same time across multiple threads.
A couple tips:
Always use synchronized(variable) on a variable that's final.
The MUTEX doesn't have to be strictly a mutex, it could be an actual object. See the example below.
Remember how the synchronized modifier on methods is effectively implemented. It's just like a synchronized block on this or MyClass.class.
Besides having an object that's strictly a mutex, you can use any field that's final. For example, to synchronize on a Map during iteration:
public class MyClass {
private static final Map<String, String> map = new HashMap<String, String>(); // Java 6
private static final Map<String, String> map = new HashMap<>(); // Java 7
public static void put(String k, String v) {
synchronized(map) {
map.put(k, v);
}
}
public static void printAll() {
synchronized(map) {
for (Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}
}
}
}
This code guarantees that you'll never get a ConcurrentModificationException
You can have both methods internally synchronize on a common lock object. Otherwise, the only way to have the instance method block while the static method executes is to synchronize on the class object (as you have in the commented lines).
Synchronized instance methods synchronize on the object instance; synchronized static methods synchronize on the class instance. Note that synchronized static methods might execute simultaneously if there are two instances of the class (say, from different class loaders). You usually would know if this is happening, because you have to do considerable work to make it happen.
Here's one way to synchronize both static and instance methods on a common lock object:
class StaticNonStaticTest {
private static final Object LOCK_OBJECT = new Object();
void nonStaticMethod() {
synchronized (LOCK_OBJECT) {
for (int i=0; i<50; i++) {
System.out.println("Non - Static method called by "
+ Thread.currentThread().getName() + " : = " + i);
}
}
}
static void staticMethod() {
synchronized (LOCK_OBJECT) {
for (int i=0; i<50; i++) {
System.out.println("Static method called by "
+ Thread.currentThread().getName() +" : = "+i);
}
}
}
}

Categories

Resources