ExecutorService fixed threads rejecting - java

I have a problem with some threads.
My script
1 - loads like over 10 millions lines into an Array from a text file
2 - creates an ExecutorPool of 5 fixed threads
3 - then it is iterating that list and add some threads to the queue
executor.submit(new MyCustomThread(line,threadTimeout,"[THREAD "+Integer.toString(increment)+"]"));
Now the active threads never bypass 5 fixed threads, which is good, but i obseved that my processor goes into 100% load, and i have debuged a little bit and i saw that MyCustomThread constructor is being called, witch means that no matter if i declare 5 fixed threads, the ExecutorService will still try to create 10 milions objects.
The main question is :
How do i prevent this? I just want to have threads being rejected if they don't have room, not to create 10 million object and run them one by one.
Second question :
How do i get the current active threads? I tried threadGroup.activeCount() but it always give me 5 5 5 5 ....
THE CALLER CLASS :
System.out.println("Starting threads ...");
final ThreadGroup threadGroup = new ThreadGroup("workers");
//ExecutorService executor = Executors.newFixedThreadPool(howManyThreads);
ExecutorService executor = Executors.newFixedThreadPool(5,new ThreadFactory() {
public Thread newThread(Runnable r) {
return new Thread(threadGroup, r);
}
});
int increment = 0;
for(String line : arrayOfLines)
{
if(increment > 10000)
{
//System.out.println("TOO MANY!!");
//System.exit(0);
}
System.out.println(line);
System.out.println(threadGroup.activeCount());
if(threadGroup.activeCount() >= 5)
{
for(int i = 0; i < 10; i++)
{
System.out.println(threadGroup.activeCount());
System.out.println(threadGroup.activeGroupCount());
Thread.sleep(1000);
}
}
try
{
executor.submit(new MyCustomThread(line,threadTimeout,"[THREAD "+Integer.toString(increment)+"]"));
}
catch(Exception ex)
{
continue;
//System.exit(0);
}
increment++;
}
executor.awaitTermination(10, TimeUnit.MILLISECONDS);
executor.shutdown();
THREAD CLASS :
public class MyCustomThread extends Thread
{
private String ip;
private String threadName;
private int threadTimeout = 10;
public MyCustomThread(String ip)
{
this.ip = ip;
}
public MyCustomThread(String ip,int threadTimeout,String threadName)
{
this.ip = ip;
this.threadTimeout = threadTimeout;
this.threadName = threadName;
System.out.prinln("MyCustomThread constructor has been called!");
}
#Override
public void run()
{
// do some stuff that takes time ....
}
}
Thank you.

You are doing it a bit wrong. The philosophy with executors is that you implement the work unit as a Runnable or a Callable (instead of a Thread). Each Runnable or Callable should do one atomic piece of work which is mutually exclusive of other Runnables or Callables.
Executor services internally use a pool of threads so your creating a thread group and Thread is not doing any good.
Try this simple piece:
ExecutorService executor = Executors.newFixedThreadPool(5);`
executor.execute(new MyRunnableWorker());
public class MyRunnableWorker implements Runnable{
private String ip;
private String threadName;
private int threadTimeout = 10;
public MyRunnableWorker(String ip){
this.ip = ip;
}
public MyRunnableWorker(String ip,int threadTimeout,String threadName){
this.ip = ip;
this.threadTimeout = threadTimeout;
this.threadName = threadName;
System.out.prinln("MyRunnableWorker constructor has been called!");
}
#Override
public void run(){ {
// do some stuff that takes time ....
}
}
This would give you what you want. Also try to test you thread code execution using visualVM to see how threads are running and what the load distribution.

I think your biggest problem here is that MyCustomThread should implement Runnable, not extend Thread. When you use an ExecutorService you let it handle the Thread management (i.e. you don't need to create them.)
Here's an approximation of what I think you're trying to do. Hope this helps.
public class FileProcessor
{
public static void main(String[] args)
{
List<String> lines = readFile();
System.out.println("Starting threads ...");
ExecutorService executor = Executors.newFixedThreadPool(5);
for(String line : lines)
{
try
{
executor.submit(new MyCustomThread(line));
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
try
{
executor.shutdown();
executor.awaitTermination(10, TimeUnit.SECONDS);
}
catch (InterruptedException e)
{
System.out.println("A processor took longer than the await time to complete.");
}
executor.shutdownNow();
}
protected static List<String> readFile()
{
List<String> lines = new ArrayList<String>();
try
{
String filename = "/temp/data.dat";
FileReader fileReader = new FileReader(filename );
BufferedReader bufferedReader = new BufferedReader(fileReader);
String line = null;
while ((line = bufferedReader.readLine()) != null) {
lines.add(line);
}
bufferedReader.close();
}
catch (Exception e)
{
e.printStackTrace();
}
return lines;
}
}
public class MyCustomThread implements Runnable
{
String line;
MyCustomThread(String line)
{
this.line = line;
}
#Override
public void run()
{
System.out.println(Thread.currentThread().getName() + " processed line:" + line);
}
}
EDIT:
This implementation does NOT block on the ExecutorService submit. What I mean by this is that a new instance of MyCustomThread is created for every line in the file regardless of whether any previously submitted MyCustomThreads have completed. You could add a blocking / limiting worker queue to prevent this.
ExecutorService executor = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.MILLISECONDS, new LimitedQueue<Runnable>(10));
An example of a blocking / limiting queue implementation can be found here:

Related

printing alternative output from 2 threads using semaphores

I am learning about the use of semaphores and multi threading in general but am kind of stuck. I have two threads printing G and H respectively and my objective is to alternate the outputs of each thread so that the output string is like this;
G
H
G
H
G
H
Each of the two classes has a layout similar to the one below
public class ClassA extends Thread implements Runnable{
Semaphore semaphore = null;
public ClassA(Semaphore semaphore){
this.semaphore = semaphore;
}
public void run() {
while(true)
{
try{
semaphore.acquire();
for(int i=0; i<1000; i++){
System.out.println("F");
}
Thread.currentThread();
Thread.sleep(100);
}catch(Exception e)
{
System.out.println(e.toString());
}
semaphore.release();
}
}
}
below is my main class
public static void main(String[] args) throws InterruptedException {
Semaphore semaphore = new Semaphore(1);
ClassA clasA = new ClassA(semaphore);
Thread t1 = new Thread(clasA);
ClassB clasB = new ClassB(semaphore);
Thread t2 = new Thread(clasB);
t1.start();
t2.join();
t2.start();
The output I am getting is way too different from my expected result. can anyone help me please? did I misuse the semaphore? any help?
Semaphores can't help you solve such a task.
As far as I know, JVM doesn't promise any order in thread execution. It means that if you run several threads, one thread can execute several times in a row and have more processor time than any other. So, if you want your threads to execute in a particular order you can, for the simplest example, make a static boolean variable which will play a role of a switcher for your threads. Using wait() and notify() methods will be a better way, and Interface Condition will be the best way I suppose.
import java.io.IOException;
public class Solution {
public static boolean order;
public static void main(String[] args) throws IOException, InterruptedException {
Thread t1 = new ThreadPrint("G", true);
Thread t2 = new ThreadPrint("O", false);
t1.start();
t2.start();
t2.join();
System.out.println("Finish");
}
}
class ThreadPrint extends Thread {
private String line;
private boolean order;
public ThreadPrint(String line, boolean order) {
this.line = line;
this.order = order;
}
#Override
public void run() {
int z = 0;
while (true) {
try {
for (int i = 0; i < 10; i++) {
if (order == Solution.order) {
System.out.print(line + " ");
Solution.order = !order;
}
}
sleep(100);
} catch (Exception e) {
System.out.println(e.toString());
}
}
}
}
BTW there can be another problem cause System.out is usually an Operation System buffer and your OS can output your messages in an order on its own.
P.S. You shouldn't inherit Thread and implement Runnable at the same time
public class ClassA extends Thread implements Runnable{
because Thread class already implements Runnable. You can choose only one way which will be better for your purposes.
You should start a thread then join to it not vice versa.
t1.start();
t2.join();
t2.start();
As others have pointed out, locks themselves do not enforce any order and on top of that, you cannot be certain when a thread starts (calling Thread.start() will start the thread at some point in the future, but this might take a while).
You can, however, use locks (like a Semaphore) to enforce an order. In this case, you can use two Semaphores to switch threads on and off (alternate). The two threads (or Runnables) do need to be aware of each other in advance - a more dynamic approach where threads can "join in" on the party would be more complex.
Below a runnable example class with repeatable results (always a good thing to have when testing multi-threading). I will leave it up to you to figure out why and how it works.
import java.util.concurrent.*;
public class AlternateSem implements Runnable {
static final CountDownLatch DONE_LATCH = new CountDownLatch(2);
static final int TIMEOUT_MS = 1000;
static final int MAX_LOOPS = 10;
public static void main(String[] args) {
ExecutorService executor = Executors.newCachedThreadPool();
try {
AlternateSem as1 = new AlternateSem(false);
AlternateSem as2 = new AlternateSem(true);
as1.setAlternate(as2);
as2.setAlternate(as1);
executor.execute(as1);
executor.execute(as2);
if (DONE_LATCH.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
System.out.println();
System.out.println("Done");
} else {
System.out.println("Timeout");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
executor.shutdownNow();
}
}
final Semaphore sem = new Semaphore(0);
final boolean odd;
AlternateSem other;
public AlternateSem(boolean odd) {
this.odd = odd;
}
void setAlternate(AlternateSem other) { this.other = other; }
void release() { sem.release(); }
void acquire() throws Exception { sem.acquire(); }
#Override
public void run() {
if (odd) {
other.release();
}
int i = 0;
try {
while (i < MAX_LOOPS) {
i++;
other.acquire();
System.out.print(odd ? "G " : "H ");
release();
}
} catch (Exception e) {
e.printStackTrace();
}
DONE_LATCH.countDown();
}
}

Threading in Sequence

I am trying to learn how to write a program which performs a given set of tasks in sequence with the help of threads. For example, Writing a program which have 3 different threads print 1111…, 22222…., 333333……, so that the output will be 1,2,3,1,2,3,1,2,3…..? OR for e.g. 2 threads one is printing odd numbers and other even numbers, but the output should be printed in sequence - i.e. one even and then odd.
I would like to learn how to write similar kind of programs in which different threads print different stuff concurrently and the output should be printed in sequence.
What is the basic concept in writing these programs. Can we use ThreadPools/Executors for the purpose ? For e.g. can we use
ExecutorService exectorService = Executors.newFixedThreadPool(3);
Can we use Future, FurtureTask, Callable, execute, submit ...? I know these concepts but I am not able to connect the dots for solving the above scenarios.
Please guide me how to go about writing these kind of programs using multithreading / concurrency.
I have written a program using wait()/notifyAll(). Following is the program. I am not executing the consumer as I am printing the whole sequence at the end. Also I am limiting the capacity of the queue to be 15. So I am basically printing the odd / even range till 15.
public class ProduceEven implements Runnable {
private final List<Integer> taskQueue;
private final int MAX_CAPACITY;
public ProduceEven (List<Integer> sharedQueue, int size) {
this.taskQueue = sharedQueue;
this.MAX_CAPACITY = size;
}
#Override
public void run() {
// TODO Auto-generated method stub
int counter = 0;
while (counter < 15) {
try {
produce(counter++);
} catch (InterruptedException e) {
e.getMessage();
}
}
}
private void produce (int i) throws InterruptedException {
synchronized (taskQueue) {
while (taskQueue.size() == MAX_CAPACITY) {
System.out.println("Queue is full : "+Thread.currentThread().getName()+" is waiting , size: "+ taskQueue.size());
taskQueue.wait();
}
Thread.sleep(1000);
if(i%2==0) {
taskQueue.add(i);
}
taskQueue.notifyAll();
}
}
}
public class ProduceOdd implements Runnable {
private final List<Integer> taskQueue;
private final int MAX_CAPACITY;
public ProduceOdd (List<Integer> sharedQueue, int size) {
this.taskQueue = sharedQueue;
this.MAX_CAPACITY = size;
}
#Override
public void run() {
int counter = 0;
while (counter < 15) {
try {
produce(counter++);
} catch (InterruptedException e) {
e.getMessage();
}
}
}
private void produce (int i) throws InterruptedException {
synchronized (taskQueue) {
while (taskQueue.size() == MAX_CAPACITY) {
System.out.println("Queue is full : "+Thread.currentThread().getName()+" is waiting , size: "+ taskQueue.size());
taskQueue.wait();
}
Thread.sleep(1000);
if(i%2==1) {
taskQueue.add(i);
}
taskQueue.notify();
}
}
}
public class OddEvenExampleWithWaitAndNotify {
public static void main(String[] args) {
List<Integer> taskQueue = new ArrayList<Integer>();
int MAX_CAPACITY = 15;
Thread tProducerEven = new Thread(new ProduceEven(taskQueue, MAX_CAPACITY), "Producer Even");
Thread tProducerOdd = new Thread(new ProduceOdd(taskQueue, MAX_CAPACITY), "Producer Odd");
tProducerEven.start();
tProducerOdd.start();
try {
tProducerEven.join();
tProducerOdd.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
ListIterator listIterator = taskQueue.listIterator();
System.out.println("Elements Are:: ");
while(listIterator.hasNext()) {
System.out.print(listIterator.next()+" ");
}
}
}
The output which I get is: Elements Are:: 02134657911810131214
The output is all jumbled up. Why is it not in sequence. 01234567891011121314 What am I missing. I would be now trying to make the program using Semaphores. Also how do we make this program using explicit locks?
Yes, you can use ExecutorService as a starting point to run your threads. You can also create and start your Threads manually, that would make no difference.
The important thing is that your Threads will run in parallel if you do not synchronize them (i.e., they have to wait for one another). To synchronize you can, e.g. use Semaphores or other thread communication mechanisms.
You wrote in the comments you have written a producer/consumer program. It's a bit of the same thing. Each time the 1-Thread produces a 1, the 2-Thread must know that it can now produce a 2. When it is finished, it must let the 3-Thread know that it must produce a 3. The basic concepts are the same. Just the threads have both producer and consumer roles.
Hi this is one sample program to print Odd and Even using two thread and using thread synchronization among them.
Also we have used Executor framework which is not mandatory, you can create thread using new Thread() as well. For quick prototype I have used system.exit() which can be replaced with graceful shutdown of threads like, interruption and all.
package com.ones.twos.threes;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class OnesTwos {
public static void main(String[] args) {
BlockingQueue<Integer> bq1 = new ArrayBlockingQueue<Integer>(100);
BlockingQueue<Integer> bq2 = new ArrayBlockingQueue<Integer>(100);
ExecutorService executorService = Executors.newFixedThreadPool(2);
try {
bq1.put(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
executorService.submit(new OddEven(bq1, bq2));
executorService.submit(new OddEven(bq2, bq1));
executorService.shutdown();
}
public static class OddEven implements Runnable {
BlockingQueue<Integer> bq1;
BlockingQueue<Integer> bq2;
public OddEven(BlockingQueue<Integer> bq1, BlockingQueue<Integer> bq2) {
this.bq1 = bq1;
this.bq2 = bq2;
}
#Override
public void run() {
while (true) {
try {
int take = bq1.take();
System.out.println(take);
bq2.offer(take + 1);
if (take > 20)
System.exit(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Mycode is also similar to Anirban's, except I am not using executor framework,
public class TestThread {
public static void main(String[] args) {
Boolean bol = new Boolean(true);
(new Thread(new Odd(bol), "odd")).start();
(new Thread(new Even(bol), "even")).start();
}
}
public class Even implements Runnable {
private Boolean flag;
public Even(Boolean b) {
this.flag = b;
}
#Override
public void run() {
for (int i = 2; i < 20; i = i + 2) {
synchronized (flag) {
try {
System.out.println(Thread.currentThread().getName()+":"+i);
Thread.sleep(1000);
flag.notify();
flag.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class Odd implements Runnable {
private Boolean flag;
public Odd(Boolean b) {
this.flag = b;
}
#Override
public void run() {
for (int i = 1; i < 20; i = i + 2) {
synchronized (flag) {
try {
System.out.println(Thread.currentThread().getName()+":"+i);
Thread.sleep(1000);
flag.notify();
flag.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
By establishing the thread pool of 3 (ExecutorService exectorService = Executors.newFixedThreadPool(3); you are essentilly limiting the executor capacity to 3 and other incoming threads will be on hold. If you want to run them in paralel you can just submit them at once. If you want to wait for each other and want to find out the result I suggest you use Callable. Personally I really like Callable because after submiting it you can just call the get method of Future, wait for a returned value from the executed thread and then continue to the next one. From the API you can see this:
/**
* Submits a value-returning task for execution and returns a
* Future representing the pending results of the task. The
* Future's {#code get} method will return the task's result upon
* successful completion.
*
*
* If you would like to immediately block waiting
* for a task, you can use constructions of the form
* {#code result = exec.submit(aCallable).get();}
And a very good example here. If you go for the Callable alternative then you don't need a Thread pool. Just a normal executor is fine. Remember to shut the executor down in the end.
class MyNumber {
int i = 1;
}
class Task implements Runnable {
MyNumber myNumber;
int id;
Task(int id, MyNumber myNumber) {
this.id = id;
this.myNumber = myNumber;
}
#Override
public void run() {
while (true) {
synchronized (myNumber) {
while (myNumber.i != id) {
try {
myNumber.wait(); //Wait until Thread with correct next number
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(id);
if (myNumber.i == 1) {
myNumber.i = 2;
} else if (myNumber.i == 2) {
myNumber.i = 3;
} else {
myNumber.i = 1;
}
myNumber.notifyAll();
}
}
}
}
In main method:
MyNumber myNumber = new MyNumber();
new Thread(new Task(1, myNumber)).start();
new Thread(new Task(2, myNumber)).start();
new Thread(new Task(3, myNumber)).start();
Hi here we have used 2 thread one to print even and another to print odd.
Both are separate and have no relation to each other.
But we have to do a synchronization mechanism between them. Also we need a mechanism to let the ball rolling, i.e. start one thread printing.
Each thread is waiting on condition and after doing it's task it lets other thread work and put ownself in waiting state.
Well happy path works fine, but we need special care when even thread is not in waiting state and the signal() from main fires, in that case even thread will never able to wake up and the program hangs.
So to make sure main thread successfully sends a signal() to even thread and even thread does not miss that we have used Phaser(with party) and checking even thread state in while loop in main.
Code is as below.
package com.ones.twos.threes;
import java.util.concurrent.Phaser;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class OnesTwosTrial2 {
public static void main(String[] args) {
Lock lk = new ReentrantLock();
Phaser ph = new Phaser(3); // to let main start the even thread
Condition even = lk.newCondition();
Condition odd = lk.newCondition();
OnesTwosTrial2 onestwostrial2 = new OnesTwosTrial2();
Thread ev = onestwostrial2.new Evens(lk, even, odd, ph);
Thread od = onestwostrial2.new Odds(lk, even, odd, ph);
ev.start();
od.start();
System.out.println("in main before arrive");
ph.arriveAndAwaitAdvance();
System.out.println("in main after arrive");
// we have to make sure odd and even thread is
// started and waiting on respective condition.
// So we used Phaser with 3, because we are having here
// 3 parties (threads)
// main, odd,even. We will signal only when all the
// threads have started.
// and waiting on conditions.
while (!Thread.State.WAITING.equals(ev.getState())) {
System.out.println("waiting");
}
lk.lock();
even.signal();
lk.unlock();
}
class Evens extends Thread {
Lock lk;
Condition even;
Condition odd;
Phaser ph;
public Evens(Lock lk, Condition even, Condition odd, Phaser ph) {
this.lk = lk;
this.even = even;
this.odd = odd;
this.ph = ph;
}
#Override
public void run() {
System.out.println("even ph");
int cnt = 0;
while (cnt < 20) {
try {
lk.lock();
ph.arrive();
even.await();
System.out.println(cnt);
cnt += 2;
odd.signal();
lk.unlock();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Odds extends Thread {
Lock lk;
Condition even;
Condition odd;
Phaser ph;
public Odds(Lock lk, Condition even, Condition odd, Phaser ph) {
this.lk = lk;
this.even = even;
this.odd = odd;
this.ph = ph;
}
#Override
public void run() {
System.out.println("odd ph");
int cnt = 1;
while (cnt < 20) {
try {
lk.lock();
ph.arrive();
odd.await();
System.out.println(cnt);
cnt += 2;
even.signal();
lk.unlock();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}

Execute certain amount of thread in a for loop

I want to build an application that executes a certain utility with multi threads. I want to control the amount of threads. Here is what I want to do:
//initialize the number of threads to be 10
for(int i = 0; i < BIG_VALUE; i++) {
RunnableObject rb = new RunnableObject(i);
rb.run();
//the for loop should run for 10 loops. When one of the threads finish its job
//the for loop continues and runs another thread. The amount of threads should
//always be 10
}
How can I do so in Java?
You can try with Java Executor framework http://docs.oracle.com/javase/tutorial/essential/concurrency/executors.html
Here an example of how to used
public class SimpleThreadPool {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
Runnable worker = new WorkerThread('' + i);
executor.execute(worker);
}
executor.shutdown();
while (!executor.isTerminated()) {
}
System.out.println('Finished all threads');
}
}
public class WorkerThread implements Runnable {
private String command;
public WorkerThread(String s){
this.command=s;
}
#Override
public void run() {
System.out.println(Thread.currentThread().getName()+' Start. Command = '+command);
processCommand();
System.out.println(Thread.currentThread().getName()+' End.');
}
private void processCommand() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
#Override
public String toString(){
return this.command;
}
}

Java ThreadPool reporting

I have a worker threadpool set up that executes a bit of work which I want to log in a central place.
To be more precise, I've extended the Thread class into a worker class, which checks the status of a concurrent queue. If it's empty, then it waits. As elements are added by another thread, notify() wakes the workers. Once they've completed the task, they wait for the next element in the queue.
What's the best practice to have each of the threads report their status at the end of each of their tasks?
public class PoolWorker extends Thread {
public ConcurrentLinkedQueue<Device> q;
public PoolWorker(ConcurrentLinkedQueue<Device> q, String type){
this.q = q;
this.type = type;
}
#Override
public void run(){
while (true)
{
Device d = null;
try{
synchronized(q){
while(q.isEmpty())
{
q.wait(); // wait for a notify()
}
d = q.remove();
}
// do some work
// report status of work completed
}
}
Try to do something like this
ExecutorService exec = Executors.newFixedThreadPool(10);
Runnable runn = new Runnable()
{
#Override
public void run()
{
System.out.println("");
}
};
exec.execute(runn);
As mentioned best way is to use BlockingQueue. Below is the sample code:
public class PoolWorker extends Thread {
public ArrayBlockingQueue<String> q;
public String type;
public PoolWorker(ArrayBlockingQueue<String> q, String type) {
this.q = q;
this.type = type;
}
#Override
public void run() {
while(true){
String work = null;
try {
System.out.println("PoolWorker.run:waiting .............");
work = q.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("PoolWorker.run..work: " + work);
}
}
public static void main(String[] args) throws InterruptedException {
ArrayBlockingQueue<String> pool = new ArrayBlockingQueue<String>(100);
PoolWorker worker = new PoolWorker(pool, "Something");
worker.start();
addWork(pool, "work1");
addWork(pool, "work2");
addWork(pool, "work3");
addWork(pool, "work4");
addWork(pool, "work5");
//Just give enough time to run
Thread.sleep(5000);
}
private static void addWork(ArrayBlockingQueue<String> pool, String work) throws InterruptedException {
System.out.println("PoolWorker.addWork: " + work);
pool.put(work);
}
}
There is nice sample code available in Java documentation as well:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html

Multithreading Synchronization not working in Java

I am trying an example of multi threading in java. There was an example on multithreading Synchronization in Java Complete reference 7th Edition. The example works fine. but when i slightly add a line to create another thread of the same class this does not work. Could some please let me know why this is happening. The example is given below. The below code is a classic exacple of producer and consumer. Where there is a single producer it works fine when i have 2 producers then it will fail. It just puts till 15 and stops.
class Q {
int n;
boolean valueSet = false;
synchronized int get() {
while (!valueSet) {
try {
wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
}
System.out.println("Got: " + n);
valueSet = false;
notify();
return n;
}
synchronized void put(int n) {
while (valueSet) {
try {
wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
}
this.n = n;
valueSet = true;
System.out.println("Put: " + n);
notify();
}
}
class Producer implements Runnable {
Q q;
Producer(Q q) {
this.q = q;
new Thread(this, "Producer").start();
//new Thread(this, "Producer2").start();
}
public void run() {
int i = 0;
while (true) {
q.put(i++);
}
}
}
class Consumer implements Runnable {
Q q;
Consumer(Q q) {
this.q = q;
new Thread(this, "Consumer").start();
}
#Override
public void run() {
while (true) {
q.get();
}
}
}
public class PCFixed {
public static void main(String[] args) {
Q q = new Q();
Producer P1 = new Producer(q);
new Consumer(q);
Producer P2 = new Producer(q);
System.out.println("Press Control-C to stop.");
}
}
Q is written to only accept one value at a time. You need to change put to be a boolean method - it returns true if valueset is true and then proceeds as normal, and returns false if valueset is false and returns without doing anything. Then the methods calling put will need to keep retrying until they get a true response. This way multiple consumers can use the same Q object without interfering with each other.
A better solution if you're using multiple producers is to use a ConcurrentLinkedQueue, which is a thread-safe queue. The producers will offer integers to the queue, and the consumers will poll the queue for integers. Multiple producers can simultaneously offer integers without interfering with each other, and multiple consumers can simultaneously poll integers without interfering with each other.
The example of concurrency you provide uses a single boolean flag to check whether there is a signal or not.
So this is more of a Semaphore arrangement than a producer consumer arrangement. It is too simplistic to deal with an arbitrary number of Threads.
If you really want to use producer consumer you are going to need a queue that holds more than one item.
static final AtomicBoolean run = new AtomicBoolean(true);
static class Producer implements Runnable {
final BlockingQueue<String> blockingQueue;
public Producer(BlockingQueue<String> blockingQueue) {
this.blockingQueue = blockingQueue;
}
#Override
public void run() {
while (run.get()) {
blockingQueue.add("Value from " + Thread.currentThread().getName());
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
//doesn't matter.
}
}
}
}
static class Consumer implements Runnable {
final BlockingQueue<String> blockingQueue;
public Consumer(BlockingQueue<String> blockingQueue) {
this.blockingQueue = blockingQueue;
}
#Override
public void run() {
while (run.get()) {
final String item;
try {
item = blockingQueue.take();
} catch (InterruptedException ex) {
return;
}
System.out.println(item);
}
}
}
public static void main(String[] args) throws InterruptedException {
final LinkedBlockingQueue<String> lbq = new LinkedBlockingQueue<>();
final ExecutorService executorService = Executors.newCachedThreadPool();
executorService.submit(new Consumer(lbq));
for (int i = 0; i < 10; ++i) {
executorService.submit(new Producer(lbq));
}
Thread.sleep(10000);
run.set(false);
executorService.shutdownNow();
}
This simple example uses a LinkedBlockingQueue to post events to and read events from.
The Producer puts Strings into the queue with it's own Thread name (they do this every 100ms). The Consumer takes from the queue and prints the String.
The queue is a BlockingQueue so the take method will block if the queue is empty.
You can easily change the number of Producers and Consumers by changing the loops that add items to the ExecutorService. Experiment, see how it works.
The AtomicBoolean flag allows the program to shutdown all the child processes spawned.
Replace each occurrence of notify with notifyAll.

Categories

Resources