A Thread as an object Java - java

I want a collection of objects that inherit from Thread; each object running in it's own thread.
I tried extends Thread and called super() thinking that'd ensure a new thread is created; but no... only main is the running thread :(
Everyone tells me, "implement Runnable put the code you want in run() and put it in a thread-object".
I can't do this because of 2-reasons:
My collection-elements aren't of-type Thread and if I polymorph I'll have to change all it's dependencies.
run() can't contain an entire class... right?
So I want to know firstly, if what I want to do is even possible and
secondly, if so, how to do it?

super() just calls the parent constructor (in your case the default Thread constructor). The method to actually start the new thread is start(). As others have said, it's poor design to extend Thread.
Yes, you can create a class that implements Runnable
class MySpecialThread implements Runnable {
public void run() {
// Do something
}
}
and you can start it in a new thread like this:
Thread t = new Thread(new MySpecialThread());
// Add it to a collection, track it etc.
t.start(); // starts the new thread
1- You can use collections of Runnables OR collections of Threads using the example below.
MySpecialThread m = new MySpecialThread();
List<Runnable> runnables = new ArrayList<Runnable>();
runnables.add(m);
List<Thread> threads = new ArrayList<Thread>();
threads.add(new Thread(m));
2- A method can't contain a class, but the above example MySpecialThread is a class that behaves like any other class. You can write a constructor, add methods and fields, etc.

I recommend to use ExecutorService
Let's have a sample code on usage of ExecutorService
import java.util.*;
import java.util.concurrent.*;
public class ExecutorServiceDemo {
public static void main(String args[]){
ExecutorService executor = Executors.newFixedThreadPool(10);
List<Future<Integer>> list = new ArrayList<Future<Integer>>();
for(int i=0; i< 10; i++){
CallableTask callable = new CallableTask(i+1);
Future<Integer> future = executor.submit(callable);
list.add(future);
}
for(Future<Integer> fut : list){
try {
System.out.println(fut.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
executor.shutdown();
}
}
class CallableTask implements Callable<Integer>{
private int id = 0;
public CallableTask(int id){
this.id = id;
}
public Integer call(){
// Add your business logic
return Integer.valueOf(id);
}
}
output:
1
2
3
4
5
6
7
8
9
10
If you want to use Thread instead of ExecutorService, below code should work for you.
import java.util.*;
class MyRunnable implements Runnable{
private int id = 0;
public MyRunnable(int id){
this.id = id;
}
public void run(){
// Add your business logic
System.out.println("ID:"+id);
}
}
public class RunnableList{
public static void main(String args[]){
List<Thread> list = new ArrayList<Thread>();
for ( int i=0; i<10; i++){
Thread t = new Thread(new MyRunnable(i+1));
list.add(t);
t.start();
}
}
}

Related

Java Multithread with shared List

I need a little help with java multithread. I have this class:
public class EdgeServer{
private static final int ServidorBordaID = 9;
private static final String urlLogin = "http://localhost/exehdager-teste/index.php/ci_login/logar";
private static final String insertSensorURI = "http://localhost/exehdager-teste/index.php/cadastros/ci_sensor/gravaSensor";
private static final String insertGatewayURI = "http://localhost/exehdager-teste/index.php/cadastros/ci_gateway/gravaGateway";
private static ArrayList<Gateway> gatewaysCadastrados = new ArrayList<>();
public static void main(String[] args) {
// Start a user thread that runs the UPnP stack
Thread clientThread = new Thread(new Descoberta());
clientThread.setDaemon(false);
clientThread.start();
Thread publicationThread = new Thread(new Publication());
publicationThread.setDaemon(false);
publicationThread.start();
}
}
The thread Descoberta will add new itens to gatewaysCadastrados list on demand. and the Publication thread will read this list and execute an action for each object on list.
I just need to know how to share and pass this var to threads. Will I need to build a semaphore to do this?
Here is the sample code where you can share list between two threads and you need to use wait and notify for semaphore.
public class Descoberta extends Thread {
private final ArrayList<Gateway> a = new ArrayList<>();
public Descoberta( ArrayList<Gateway> a) {
this.a = a;
}
#Override
public void run() {
synchronized (a) {
while(true){ // your condition
a.wait();
}
a.notify();
}
}
}
public class Publication extends Thread {
private final ArrayList<Gateway> b = new ArrayList<>();
public Publication(ArrayList<Gateway> b) {
this.b = b;
}
#Override
public void run() {
synchronized (b) {
while(true){ // your condition
b.wait();
}
b.notify();
}
}
}
public class EdgeServer {
public static void main(String args[]) {
private final ArrayList<Gateway> gatewaysCadastrados = new ArrayList<>();
Thread clientThread = new Descoberta(gatewaysCadastrados);
Thread publicationThread = new Publication(gatewaysCadastrados);
clientThread.start();
publicationThread.start();
}
}
A simple way it to pass the shared object as a constructor parameter to the relevant runnables; e.g.
Thread clientThread = new Thread(new Descoberta(gateways));
...
Thread publicationThread = new Thread(new Publication(gateways));
Obviously, the respective Runnable constructors need to save the parameters so that their run() methods can find them.
There are various other ways:
If the runnables are inner classes within the same outer class instance, they can access shared objects in outer class.
If the shared state is stored in static variables, then the runnables can access them via static getters, etcetera. (NOTE: this is most likely bad design ...)
And as #Fidor points out, if two or more threads are going to share a common (mutable) data structure, then they need to synchronize their read and write operations on the data structure. If you neglect this, your application is liable to have the kind of insidious bugs that are hard to reproduce and hard to track down.

User Created Thread Pool Shutdown having different behaviour when a sysout is added

I was asked to create my own thread pool in an interview where I have to create the number of threads requested by the user. Allow user to submit there task and finally shutdown the pool. I wrote the below program which is working fine in all the cases other than shutdown.
public class ThreadPool
{
public final Queue<Runnable> workerQueue;
private static boolean isrunning = true;
private Thread[] workerThreads;
public ThreadPool(int N)
{
workerQueue = new LinkedList<>();
workerThreads = new Thread[N];
for (int i = 0; i < N; i++) {
workerThreads[i] = new Worker("Pool Thread " + i);
workerThreads[i].start();
}
}
public void shutdown()
{
while(isrunning){
if(workerQueue.isEmpty()){
isrunning = false;
}
}
}
public void submit(Runnable r) throws Exception
{
workerQueue.add(r);
}
private class Worker extends Thread
{
public Worker(String name)
{
super(name);
}
public void run()
{
while (isrunning) {
try {
if(!workerQueue.isEmpty())
{
Runnable r = workerQueue.poll();
r.run();
}
} catch (RuntimeException e) {
e.printStackTrace();
}
}
}
}
}
The Test method I wrote is like below
static public void main(String[] args) throws Exception
{
ClassA a1 = new ClassA();
ClassA a2 = new ClassA();
ClassA a3 = new ClassA();
ClassA a4 = new ClassA();
ClassA a5 = new ClassA();
ClassA a6 = new ClassA();
ThreadPool tp = new ThreadPool(5);
tp.submit(a1);
tp.submit(a2);
tp.submit(a3);
tp.submit(a4);
tp.submit(a5);
///////////////
tp.submit(a6);
tp.shutdown();
}
But the program is never ending, its running always and I have to stop it manually in eclipse. But if I add a simple System.out.print("") in my method shutdown, its working perfrectly(the Program is ended after the execution of all the threads).
Can you please tell me why its working with the sysout and why its not working with out it ?
You have two major problems with your code:
You are using an implementation of Queue that's not synchronized in a multithread environment. This leads to a Race Condition when multiple threads insert/remove from the queue. Please consider using something like:
workerQueue = new ConcurrentLinkedQueue()
You run some very tight loops, one in your Worker.run() method where you're not checking for NPE and not allowing for some "cooldown", and another one in shutdown():
while (isrunning) {
...
Runnable r = workerQueue.poll();
r.run();
...
}
This, coupled with 1, leads to the Queue being emptied without properly updating the size info: ie. isEmpty() returns false but poll() returns null. Your program will become stuck in a loop. This doesn't happen when you add System.out.print() due to different timing specific to your configuration (it can continue to fail in other environments - especially where there are more than 6 cpu cores available).

ExecutorService with Runnable share CyclicBarrier

I have a problem in a concurrent solution in Java using n Runnable class that share a CyclicBarrier, and the Runnable are handled by a ExecutorService, this is the code:
public class Worker implements Runnable {
private CyclicBarrier writeBarrier;
private int index;
private int valuetocalculate;
public Worker(int i,CyclicBarrier writeBarrier)
{
this.writeBarrier = writeBarrier;
this.index = i;
this.valuetocalculate = 0;
}
public void run() {
//calculations with valuetocalculate
writeBarrier.await();
//write new valuetocalculate value
}
}
public class Context {
private ArrayList<Worker> workers;
private Chief chief;
public Context()
{
workers = new ArrayList<Worker>();
chief = new Chief();
}
public void generateRandomWorkers(nworkers)
{
writeBarrier = newWriteBarrier(workers);
chief.setBarrier(writeBarrier);
//generate random woker
for (int i = 0; i<nworkers;i++)
{
Worker worker = new Worker(i,writeBarrier);
workers.add(worker);
}
chief.setWorkersArray(workers);
chief.start();
}
}
public class Chief extend Thread {
private CyclicBarrier writeBarrier;
private ArrayList<Worker> workers;
private ExecutorService executor;
private int cores;
public Chief ()
{
cores = Runtime.getRuntime().availableProcessors()+1;
}
public void setBarrier (CyclicBarrier writeBarrier)
{
this.writeBarrier = writeBarrier;
}
public setWorkersArray(ArrayList<Worker> workers)
{
this.workers = workers;
}
public ArrayList<Integer> getvaluetocalculate()
{
ArrayList<Integer> values = new ArrayList<Integer> ();
for (int i = 0; i<workers.size();i++)
{
values.add(workers.get(i).valuetocalculate);
}
return values;
}
public void run(){
while (!stop) //always true for testing
{
getvaluetocalculate();
//make calculations
writeBarrier.reset();
executor = Executors.newFixedThreadPool(cores);
for (int i = 0;i<workers.size();i++)
{
Runnable runnable = workers.get(i);
executor.execute(runnable);
}
executor.shutdown();
while (!executor.isTerminated())
{
}
}
}
}
All start in the main with:
Context = new Context();
context.generateRandomWorkers();
The problem is that the Runnable doesn't go over the first "iteration" in the run of the Chief, so seems that the problem is that the Workers doesn't go over the writerBarrier.await();, instead if I initialized this:
executor = Executors.newFixedThreadPool(cores);
with the workers.size(), works but seems not synchronized...how I can solve?
OK so it looks like you are trying to do the following
One chief/scheduler which controls the workers
One or more workers doing calculations
Chief executes all workers
Chief waits for all workers to complete
Chief gets results from each Worker to calculate result
Assuming the above here are your problems.
Doing the barrier.await() in the worker run() method prevents that thread from being released back to the pool to run subsequent workers. Therefore the when pool size < worker size the first 'pool size' workers consume the threads and then stop waiting for the others which can't run. This is why not all your workers run unless you change the pool size to workers.size().
The valuetocalculate variable is not synchronised between the worker setting the result and the chief reading it so you might be seeing stale results.
The correct way to implement this sort of system is to have the workers implement Callable where the callable returns the result once the worker has calculated. This takes care of publishing the results back to your chief (you'll see below how this works).
Remove the cyclic barrier, you don't need that.
Create the executor as you are now and call invokeAll() with a list of Callables (your workers). This method invokes the Callables using the executor and waits for them to complete. It blocks until all workers have completed at which point it will return a List<Future<T>>. Each Future corresponds to one of the workers/Callables you passed in. Iterate the list pulling the results out. If a worker has failed trying to get() the result from it's Future will throw an exception.
Hope that helps.

how can I insert data with thread in jdbc?

I want to insert data with using JDBC.
I write this code :
//I want to start threads here
while(stmt_ver.next()){
stmt_ver.setString(i, "test"+... );
stmt_ver.executeBatch();
connection_ver.commit();
}
//I want to finish threads here
How can I do this with thread?
Here you go. Updated answer with code
Threaded class
public class MyThreadedClass extends Thread{
//Do what I need here on a thread
public void run(){
//Do what I need here
}
}
Main
//Main class
public static class MyProgramMain{
//Program main
public static void main(String[] args) {
//Send 10 threads
for (int i=0; i<10; i++){
//Init class (threaded)
MyThreadedClass threadedClass = new MyThreadedClass();
//Execute code in the class run() method
threadedClass.start();
}
}
}
Your question is hard to answer. You are asking very vague. Try to be clear. Post all necessary code. Try to explain what you did and what you would like to do.
Here is some hint for you. It will not run if you copy and past it, but I think it should make clear what you can try:
int i = 0;
while(i < columnCount ){
// make a new statement
Statement stmt_ver = new Statement();
// set your data and make the statement ready
stmt_ver.set...
// make a new thread that executes your data
// and let it run
new Thread(){
public void run(){
stmt_ver.addBatch();
stmt_ver.executeBatch();
connection_ver.commit();
}
}.start();
i++;
}
This is a very simple solution. It will start a thread it each iteration. Since I/O typically is taking some time, this could improve the execution time of your code. But be aware - threading is not easy. This is a very simple, naive solution. It could cause more problems than it solves. If you are not familiar with threads (and it seems like you are not) don't do it!
new Thread(new Runnable(){
#Override public void run(){
//enter code here
}
}).start();
EDIT You want to insert with many threads in parallel ...
There are many different possibilities.
You should read about: Concurrency (concurrent collections) and Executors.
EDIT 2 I agree with Thomas Uhrig , that introducing Threads could be more a harm than a blessing here.
Why do you think it would be helpful?
public class MockCommonDao {
ArrayList<ArrayList> listOlists = new ArrayList<ArrayList>();
public List CommonInsert(List<Object> example)
{
List<Future<Object>> listOlists = null;
ExecutorService executor = Executors.newFixedThreadPool(example.size());
List<TransactionImpl> callingList = new ArrayList<MockCommonDao.TransactionImpl>();
for (int i = 0; i < example.size(); i++) {
TransactionImpl localImpl = new TransactionImpl(example.get(i));
callingList.add(localImpl);
}
try {
listOlists = executor.invokeAll(callingList);
} catch (InterruptedException e) {
}
return listOlists;
}
private class TransactionImpl implements Callable<Object>{
private Object example;
TransactionImpl(Object Criteria) {
this.example = Criteria;
}
#Override
public Object call() throws Exception {
private class TransactionImpl implements Callable<Object>{
private Object example;
TransactionImpl(Object Criteria) {
this.example = Criteria;
}
#Override
public Object call() throws Exception {
while(stmt_ver.next()){
stmt_ver.setString(i, "test"+... );
stmt_ver.executeBatch();
connection_ver.commit();
}
}
}}
}
This code will make simualtaneous insert depending on value of your threads you want to create for insert.example.size() determines number of insert operations you want to perform.Hope you mean this.

Returning a value from Runnable

The run method of Runnable has return type void and cannot return a value. I wonder however if there is any workaround of this.
I have a method like this:
public class Endpoint {
public method() {
Runnable runcls = new RunnableClass();
runcls.run()
}
}
The method run is like this:
public class RunnableClass implements Runnable {
public JaxbResponse response;
public void run() {
int id = inputProxy.input(chain);
response = outputProxy.input();
}
}
I want to have access to response variable in method. Is this possible?
Use Callable<V> instead of using Runnable interface.
Example:
public static void main(String args[]) throws Exception {
ExecutorService pool = Executors.newFixedThreadPool(3);
Set<Future<Integer>> set = new HashSet<>();
for (String word : args) {
Callable<Integer> callable = new WordLengthCallable(word);
Future<Integer> future = pool.submit(callable);
set.add(future);
}
int sum = 0;
for (Future<Integer> future : set) {
sum += future.get();
}
System.out.printf("The sum of lengths is %s%n", sum);
System.exit(sum);
}
In this example, you will also need to implement the class WordLengthCallable, which implements the Callable interface.
public void check() {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Integer> result = executor.submit(new Callable<Integer>() {
public Integer call() throws Exception {
return 10;
}
});
try {
int returnValue = result.get();
} catch (Exception exception) {
//handle exception
}
}
Have a look at the Callable class. This is usually submited via an executor service
It can return a future object which is returned when the thread completes
Yes, there are workaround. Just use queue and put into it value which you want to return. And take this value from another thread.
public class RunnableClass implements Runnable{
private final BlockingQueue<jaxbResponse> queue;
public RunnableClass(BlockingQueue<jaxbResponse> queue) {
this.queue = queue;
}
public void run() {
int id;
id =inputProxy.input(chain);
queue.put(outputProxy.input());
}
}
public class Endpoint{
public method_(){
BlockingQueue<jaxbResponse> queue = new LinkedBlockingQueue<>();
RunnableClass runcls = new RunnableClass(queue);
runcls.run()
jaxbResponse response = queue.take(); // waits until takes value from queue
}
}
If you add a field to RunnableClass you can set it in run and read it in method_. However, Runnable is a poor (the Java keyword) interface as it tells you nothing about the (the concept) interface (only useful line of the API docs: "The general contract of the method run is that it may take any action whatsoever."). Much better to use a more meaningful interface (that may return something).
One way is, we have to use Future - Callable approach.
Another way is, Instead of returning value, you can hold in object
Example:
class MainThread {
public void startMyThread() {
Object requiredObject = new Object(); //Map/List/OwnClass
Thread myThread = new Thread(new RunnableObject(requiredObject)).start();
myThread.join();
System.out.println(requiredObject.getRequiredValue());
}
}
class RunnableObject implements Runnable {
private Object requiredObject;
public RunnableObject(Object requiredObject) {
this.requiredObject = requiredObject;
}
public void run() {
requiredObject.setRequiredValue(xxxxx);
}
}
Because object scope is in the same scope so that you can pass object to thread and can retrieve in the main scope. But, most important thing is, we have to use join() method. Because main scope should be waiting for thread completion of its task.
For multiple thread case, you can use List/Map to hold the values from threads.
Try the following
public abstract class ReturnRunnable<T> implements Runnable {
public abstract T runForResult();
#Override
public void run() {
runForResult();
}
}
Take a look at the callable interface, perhaps this suites your needs. You can also try to get the value of the response field by calling a setter-method inside of your run() method
public void run() {
int id;
id =inputProxy.input(chain);
response = outputProxy.input();
OuterClass.setResponseData(response);
}

Categories

Resources