I’m new to multithreading.
I’m having difficulties understanding what is wrong with my implemantation, and why every implementation I see is using synchronized blocks and notifys.
The running seems ok so i can’t point to what exactly is not good but I assume there are some multithreading principles I'm not following.
This is the code:
public class Threads {
static Queue<MyThread> queue = new LinkedList<>();
static Thread[] threadsArr = new Thread[10];
public static void main(String[] args) throws InterruptedException {
Threads t = new Threads();
t.startArr();
t.startProcess();
}
void startArr(){
for (int i=0;i<10;i++){
threadsArr[i] = new Thread(new MyThread(i));
}
}
void startProcess(){
for (int i=0;i<100;i++){
queue.add(new MyThread(i));
}
for (int i=0;i<100;i++){
int insertPlace = 0;
boolean isFull = true;
while (isFull){
for (int j=0;j<10;j++){
if (!threadsArr[j].isAlive()){
insertPlace = j;
isFull = false;
}
}
}
threadsArr[insertPlace] = new Thread(new MyThread(i));
threadsArr[insertPlace].start();
}
}
}
and the MyThread class:
public class MyThread implements Runnable {
int threadNumber;
public MyThread(int threadNumber){
this.threadNumber = threadNumber;
}
#Override
public void run() {
System.out.println(threadNumber + " started.");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(threadNumber + " finished.");
}
}
thanks.
I think the main problem is that you missed the role of a "ThreadPoolExecutor". Basically, the user that uses your class wants to be able to call an "execute(Runnable run)" method, knowing that your Threads class will handle the execution in the process it is allowed to create.
You should rework the API of your class and provide this kind of method (see real ThreadPoolExecutor for instance http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html).
Second, if you are training for a job interview, try to write cleaner and more flexible code by not having constant like "10" all around the class. This should be an attribute provided by the user of your class (in the constructor), specifying how many threads at once he wants to allow (again see the real ThreadPoolExecutor).
Finally I am no expert in implementing ThreadPoolExecutors, but you could consider using a BlockingQueue (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html) which support, i quote, "operations that wait for the queue to become non-empty when retrieving an element". This could be useful for waiting for a Thread to be available, rather to do it yourself. But I guess there are better answers.
Good luck,
Mathias
Related
Is it possible in java to create a thread that will always work in the background? The problem is that the application instance sometimes crashes with an OutOfMemoryException. Therefore, several instances are launched in parallel. Each instance does some work: it saves something to the database at the request of the user. And the stream, which should work constantly, will look into the database and somehow process the information from it.
Most likely, the sheduler will not work, since the thread must be running constantly and wait for a signal to start working.
First of all, I suggest you investigate and resolve the OutOfMemoryException because it better to avoid these cases. You can instanziate a thread that wait for a request, execute a request and then return to wait for another request. The implementation is like this for thread:
/** Squares integers. */
public class Squarer {
private final BlockingQueue<Integer> in;
private final BlockingQueue<SquareResult> out;
public Squarer(BlockingQueue<Integer> requests,
BlockingQueue<SquareResult> replies) {
this.in = requests;
this.out = replies;
}
public void start() {
new Thread(new Runnable() {
public void run() {
while (true) {
try {
// block until a request arrives
int x = in.take();
// compute the answer and send it back
int y = x * x;
out.put(new SquareResult(x, y));
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
}).start();
}
}
And for the caller method:
public static void main(String[] args) {
BlockingQueue<Integer> requests = new LinkedBlockingQueue<>();
BlockingQueue<SquareResult> replies = new LinkedBlockingQueue<>();
Squarer squarer = new Squarer(requests, replies);
squarer.start();
try {
// make a request
requests.put(42);
// ... maybe do something concurrently ...
// read the reply
System.out.println(replies.take());
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
To more information, you can start to read the post that I found here to provide you the example.
You basically need an infinitely running thread with some control.
I found this answer to be the simplest and it does what you need.
https://stackoverflow.com/a/2854890/11226302
I'm learning Java threads and want my code to output threads 0-9 in sequential order. I used the synchronized keyword but I don't get the results I expect.
What should I do to correct my code?
public class MyThread extends Thread {
private static final int threadMax = 10;
private static int runCount = 0;
public void printThread() {
synchronized (this) {
while (runCount++ < 100) {
System.out.println(runCount + ": " + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public void run() {
printThread();
}
public static void main(String[] args) {
for (int i = 0; i < threadMax; i++) {
new MyThread().start();
}
}
}
It is not working as every time you are creating new MyThread object and you are synchronized over that new object. So, every Thread you created will get a lock on the diffrent object. So, you should pass a common object to take the lock like below.
class MyThread extends Thread {
private static int runCount = 0;
Object lock;
public MyThread(Object lock) {
this.lock = lock;
}
public void printThread() {
synchronized (lock) {
// your code here
}
}
//.........
}
And then call it like :
Object lock = new Object();
for (int i = 0; i < threadMax; i++) {
new MyThread(lock).start();
}
However, the above program will not ensure you that it will run in sequence. There are several ways to do that. You can use wait() and notify() to achieve your goal. Refer the below example :
public void printThread() {
while (runCount < 90) {
synchronized (lock) {
while (runCount % 10 != remainder) {
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(runCount + ": " + Thread.currentThread().getName());
runCount++;
lock.notifyAll();
}
}
}
And call the thread like :
Object lock = new Object();
for (int i = 0; i < 10; i++) {
new MyThread(lock, i).start();
}
You are synchronizing the context of the thread, which is different for each one. You should put into the synchronized key any common object for all diferent threads. This won't make them run in any certain secuence, just to wait each other to end.
If you want to test the synchronized keyword for any purpose, you could pass the constructor a common variable and use it in every thread:
public class MyThread extends Thread {
private static final int threadMax = 10;
private static int runCount = 0;
private Object test; //Object pointing main method
public MyThread(Object test){
this.test = test; //This won't copy values as it is an object and not a number, string...
}
public void printThread() {
synchronized (test) { //Same object for all threads
while (runCount++ < 100) {
System.out.println(runCount + ": " + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public void run() {
printThread();
}
public static void main(String[] args) {
Object test; //common object
for (int i = 0; i < threadMax; i++) {
new MyThread(test).start();
}
}
}
If you want also to make them start in order, you should "synchronize" the loop making wait and notify calls.
Anyway, the point about multithreading is to have several threads running at the "same" time and not in sequence, as that would be the same as a linear execution.
You have several tasks that you want to delegate to threads but have them executed sequentially.
As others have pointed out, wait & notify can help you achieve that : wait until Nth have finished then notify the next. However, if you wait/notify inside your printThread method, as all your threads are waiting simultaneously on the same lock, there is no guaranties that N+1th thread will be next. So you may have
1: thread-1
...
10: thread-1
11: thread-5
...
20: thread-5
21: thread-2
...
If that's ok for you, you're done. However, in a situation where you specifically want your threads to be ordered, what you need is a waiting queue (FIFO : First In First Out).
To achieve that, you can use the awesome ExecutorService. Be aware however that they hide the Threads from you and picking that solution should not be at the cost of understanding the basics of them beforehand.
An ExecutorService is a very convenient class that can receive tasks (in the form of a Runnable, see below) and will execute them in separate Threads.
Here, I'm using a SingleThreadExecutor which execute the submitted tasks sequentially. So all you have to do is call it's execute method with your tasks as arguments, and the ExecutorService will run them in the right order, one after the other.
Here's what you can do with a few notes :
public class ThreadRunner {
// Note : Constants are usually all uppercase in Java
private static final int MAX_THREADS = 10;
private final int threadName;
public ThreadRunner(int threadName) {
this.threadName = threadName;
}
public void printThread() {
// Note: For loops are better than while when you already know the number of iterations
for (int runCount = 0; runCount < 10; runCount++) {
System.out.println(runCount + "th run from thread " + threadName);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
for (int i = 0; i < MAX_THREADS; i++) {
int threadName = i + 1;
// Submit a task to the executor
executorService.execute(() -> new ThreadRunner(threadName).printThread());
}
// Nicely ask for the executor to shutdown.
// Then wait for already submitted tasks to terminate.
executorService.shutdown();
try {
executorService.awaitTermination(120, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I changed a few details, here are the reasons :
Thread creation : don't inherit from Thread
I would advise you not to inherit from Thread, but create a local instance of it, as all you need is to use a Thread ; you don't want to be a Thread :
public static void main(String[] args) {
// Using Java 1.8+ lambda
Thread lambdaThread = new Thread(() -> System.out.println("Hello from a lambda in a Thread"));
lambdaThread.start();
// Using an anonymous class for java <1.8
Thread anonClassThread = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("Hello from an anonymous class in a Thread");
}
});
anonClassThread.start();
}
You're creating a new Thread passing a Runnable as constructor argument, using either lambda or anonymous class, depending of your Java version.
A Runnable is simply a portion of code that will be executed (by a Thread, in this case).
Same apply to ExecutorService, it's execute methode takes a Runnable which I've created through lambdas.
Sharing static counter between threads
Your line private static int runCount = 0; is a static field, which means it is shared by all instances of the class MyThread. When you increase it in a thread, all threads will read (and write) to the same variable.
If your threads were running sequentially, the first would do it's 100 iterations, then when the second thread starts, runCount is already at 100 and you're not entering your while loop. If that wasn't intended, it may be confusing when you'll test your code.
Based on your expected output in a comment, I believe you want your threads to do 10 iterations each, not share a pool of 100 iterations and manage somehow to have each of them only perform 10.
Having the name of the thread belong to each ThreadRunner
Small detail here : previously, you were creating 10 threads. Here, the ExecutorService only creates one that he reuse for each task you submit. So Thread.currentThread().getName() would always be thread-1.
You wouldn't be able to see which task is running without this field.
If each task is started after the previous, you don't need 10 Threads, but a single Thread performing the 10 tasks sequentially.
I've been as complete as possible, but some points might be a little bit tricky, so don't hesitate to ask for clarifications!
I'm trying to write a thread that I can delegate testing and evolution of a robot to while I sort the existing chromosomes by fitness in the main thread. Below is the initial fitness method. What I want to do here is to have each genome tested by a robotHandler as the tests are 30 - 40 seconds long. I will only be running one of these threads at any given time.
Currently I seem to get caught in the wait() section of the intialFitness method. This is my first attempt at multithreading so any help as to how to debug the problem or if someone can spot the issue that would be fantastic
The RobotInterface class is just a testing class at the moment, I have commented out the log4j and sleep declarations to try and rule these out (Incidentally log4j was not logging anything in the thread if that helps)
public synchronized ArrayList<Genome> initialFitness( ArrayList<Genome> population)
{
for ( int i = 0; i < population.size(); i++ )
{
candidateTest = new CandidateTest(population.get(i));
Thread robotHandler = new Thread(new RobotInterface( candidateTest));
while(! (candidateTest.finishedYet() ))
{
try
{
wait();
}
catch (InterruptedException e)
{
logger.debug("The initialFitness method was interrupted, this shouldn't happen");
}
}
population.set(i, candidateTest.getCandidate());
}
return population;
}
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import java.util.Random;
The RobotInterface Class
public class RobotInterface implements Runnable
{
// create a serial connection
// transmit a string and check for response
// wait for evaluation
// take evaluation
private CandidateTest candidate;
private Random rng = new Random();
//protected static Logger logger = Logger.getLogger("Thread" + Thread.currentThread().getName());
public RobotInterface(CandidateTest test)
{
this.candidate = test;
//PropertyConfigurator.configure("log4j.properties");
}
public void evaluate (Genome genome)
{
//send to robot and return fitness
genome.setFitness(rng.nextDouble());
//logger.debug("fitness is " + genome.getFitness());
try
{
//logger.debug("Thread sleeping for 4 seconds");
//Thread.sleep(4000);
}
catch(Exception E)
{
}
}
public void run()
{
//logger.debug("entering run of Robot Interface");
//logger.debug("Send Genome via serial and wait for a response");
Genome testSubject = candidate.getCandidate();
evaluate(testSubject);
candidate.finished();
notifyAll();
}
}
The CandidateTest Class
public class CandidateTest
{
private volatile Genome candidate;
private volatile boolean testFinished = false;
public CandidateTest(Genome g)
{
candidate = g;
}
public synchronized Genome getCandidate()
{
return candidate;
}
public synchronized void finished()
{
testFinished = true;
}
public synchronized boolean finishedYet()
{
return testFinished;
}
}
First, you are not starting the robotHandler thread. So your main thread gets to wait() and then no other thread ever comes along to notify it.
Second, you call wait() on whatever class initialFitness belongs to, but you call notifyAll() on RobotInterface. So RobotInterface will notify everyone who is waiting on it (nobody) and your main code will continue to wait. You need to call notifyAll() on the same object on which you called wait().
I suggest
synchronized(candidateTest) {
candidateTest.wait();
}
and
candidateTest.notify();
Never seen where the Thread is started. Try:
Thread robotHandler = new Thread(new RobotInterface( candidateTest)).start();
so your notifyAll() is never called
Nathanial hit the nail on the head but I would suggest using the java.util.concurrent package if you are just getting started with concurrency in Java. Found a nice beginners article on DZone for you: http://java.dzone.com/articles/lazy-developers-introduction
I have to write this produce consumer application using multithreading. I wrote the following java code but havn;t been able to figure out where it is getting wrong. Also i want to know whether my class design is apt or if my coding style is appropriate.
Thanks in Advance!!!
EDIT
I have modified the produce consumer code: But it still has some problem.
import java.util.*;
import java.lang.Thread;
public class pc_example {
public static void main (String [] args) {
Store store = new Store( 10 );
produce p = new produce(store);
consume c = new consume (store);
p.start();
c.start();
}
}
class Store {
public Queue<Integer> Q;
public int max_capacity;
Store( int max_capacity ) {
Q = new LinkedList<Integer>();
this.max_capacity = max_capacity;
}
}
class produce extends Thread {
private Store store;
private int element;
produce ( Store store ) {
this.store = store;
this.element = 0;
}
public void put() {
synchronized (store) {
if (store.Q.size() > store.max_capacity) {
try {
wait();
} catch (InterruptedException e) {}
}
else {
element ++;
System.out.println( "Producer put: " + element );
store.Q.add(element);
notify();
}
}
}
}
class consume extends Thread {
private int cons;
private Store store;
consume (Store store) {
this.store = store;
this.cons = 0;
}
public void get() {
synchronized (store) {
if (store.Q.size() == 0) {
try {
wait();
} catch (InterruptedException e) {}
}
else {
int a = store.Q.remove();
System.out.println( "Consumer put: " + a );
cons++;
if (store.Q.size() < store.max_capacity)
notify();
}
}
}
}
You are creating two instances of Producer_Consumer which are having their own queues, so there's no sharing between. You should not instantiate the queue in the classes, but provide it outside as a constructor argument.
class Producer_Consumer extends Thread {
private final Queue<Integer> queue;
Producer_Consumer(int mode, Queue<Integer> queue)
{
this.queue = queue;
}
public static void main(String[] args)
{
Queue<Integer> queue = new LinkedQueue<Integer>();
Producer_Consumer produce = new Producer_Consumer(queue, 2);
Producer_Consumer consume = new Producer_Consumer(queue, 1);
produce.start();
consume.start();
}
}
Further improvements could be done as suggested using a blocking queue from java.util.concurrent package. There's really no need of using Object's methods wait() and notify() for this kind of tasks.
For a complete example see the producer-consumer example in the java api for BlockingQueue.
There are several errors in the code. For the first the producer and the consumer are not using the same queue e.g. there are two instances of the queues. Secondly notify and wait methods are also operating on different objects.
Getting your example to work needs several things:
Only one queue
Thread safe handling of the queue
Handling notification and waiting on the same object
The producer code could be rewritten to:
public void produce() {
int i = 0;
while (i < 100) {
synchronized(Q) {
if (Q.size() < max_capacity) {
Q.add(i);
System.out.println("Produced Item" + i);
i++;
Q.notify();
} else {
try {
Q.wait();
} catch (InterruptedException e) {
System.out.println("Exception");
}
}
}
}
}
1, Use appropriate types. Your mode is much better off as en enumeration instead as an int.
2, Your conduit between the threads, Q, isn't actually shared since it is not declared static.
You would have problems anyway since linkedlist isn't synchronized.
Synchronizing produce() and consume()makes no difference.
This is what a BlockingQueue is for.
Each of your objects is working on a a different instance of the
Queue<Integer> Q
so the producer puts stuff into one, but the consumer never looks in that one - it's trying to get items from a Q that never gets anything put into it.
However, once you address that you need to make sure that the Queue<> object is handled in a threadsafe manner. While the produce() and consume() methods are each synchronized, the synchronization at this level won't help since you're dealing with two distinct Producer_Consumer objects. They need to synchronize their access to the shared resource some other way.
I suggest to look at the classes in java.util.concurrent (available from Java 1.5). In particular, instead of a Queue, you might use a BlockingQueue.
It allows you to produce:
try {
while(true) { queue.put(produce()); }
} catch (InterruptedException ex) { ... handle ...}
and consume:
try {
while(true) { consume(queue.take()); }
} catch (InterruptedException ex) { ... handle ...}
Otherwize, (if this is an exercise on java synchronization), you should
improve the visibility of fields (why only max_capacity is private?)
improve the design (I prefer to create two separate classes for producers and consumers)
ensure that producers and consumers wait and notify on the SAME object
make producers and consumers work on the same queue
Run methods are missing in your Thread classes. So your threads did start and finish doing nothing. Rename the put and get methods to run and use while loop. Also note that you need to call the notify and wait on the store (monitor).
public void run() {
while(true){
synchronized (store) {
if (store.Q.size() > store.max_capacity) {
try {
store.wait();
} catch (InterruptedException e) {}
}
else {
element ++;
System.out.println( "Producer put: " + element );
store.Q.add(element);
store.notify();
}
}
}
}
I have a project for my "Operating Systems". I need to write 2 programs with java...
write a program that produce Water with 2 method Oxygen and Hydrogen.
method Oxygen produce one Oxygen and method Hydrogen produce one hydrogen. when 2 Hydrogen and one Oxygen was existed H2O created. I must write this with with Semaphores and threads.
Write the above problem with Monitors and Sychronize.
I've writed some code for this but it gives illegal monitor exeption...
please help me to correct it...
This is my code:
// class for implement Thread for oxygen
public class Thread_O implements Runnable {
public void run() {
thread t = new thread();
try {
t.oxygen();
} catch (InterruptedException ex) {
Logger logger = Logger.getLogger(Thread_O.class.getName());
logger.log(Level.SEVERE, null, ex);
}
}
}
// class for implement Thread for Hydrogen
public class Thread_H implements Runnable {
public void run() {
thread t = new thread();
try {
t.Hydrogen();
} catch (InterruptedException ex) {
Logger logger = Logger.getLogger(Thread_H.class.getName());
logger.log(Level.SEVERE, null, ex);
}
}
}
//class for method Oxygen and Hydrogen
public class thread {
Semaphore O = new Semaphore(0, true);
Semaphore H = new Semaphore(0, true);
Semaphore H2O = new Semaphore(0, true);
Semaphore safe = new Semaphore(1, true);
public void oxygen() throws InterruptedException {
safe.wait();
H.wait();
H.wait();
H2O.release();
H2O.release();
Safe.release();
// System.out.println("O2...!");
}
public void Hydrogen() throws InterruptedException {
H.release();
H2O.wait();
// System.out.println("H2...!");
}
}
and in action of Oxygen Button:
Thread th = new Thread(new Thread_O());
th.start();
I'm not going to decode your homework for you, but an IllegalMonitorException is thrown when you're trying to wait() on an object without being synchronized. So to wait for an object called list:
synchronized (list) {
try {
list.wait();
} catch(Throwable t) {
t.printStackTrace();
}
}
You have to understand how the producer/consumer mechanism work.
Here you'll have one consumer thread and two producers.
First you'll have one thread producing oxygen, and other producing hydrogen.
Then, those molecules should be places "somewhere" ok? That "something" is the thing that has to be monitored and synchronized.
So it should go something like this:
class Water {
char [] waterMolecule = new char[3]; // <-- synchronize access to this
char hydrogen(){
return 'H';
}
char oxygen() {
return 'O';
}
void produce() {
Thread t = new Thread( new Runnable() {
synchronize( waterMolecule ) {
waterMolecule[0] = hydrogen();
}
}):
.... produce the others
}
void consume() {
synchronize watermolecule
if waterMolecule is complete
create water and clean out the molecule.
}
}
That's the basic idea.
Just bear in mind that you won't be able to produce another particle of oxigen until the previous one has been consumed.
Also you must always call wait in a while loop
Here's how that wait/synchronize should be coded.
Here's a number of producer/consumer samples.
Although your homework is already due, I'd like to propose CyclicBarrier as the best solution for this scenario.
It allows some kind of rendezvous for the different threads (here: your molecule producers) and triggers the execution of an additional runnable on completition (here: creation of h20).