public class ClassTest extends Thread{
public static Object lock = new Object();
public static LinkedList<Integer> stack;
public SortedSet<Integer> set= new TreeSet<>();
#Override
public void run(){
synchronized(lock){
// try{
// this.wait();
// }
// catch(Exception e){
// e.printStackTrace();
// }
while(!stack.isEmpty()){
set.add(stack.pop());
this.yield();
// this.notifyAll();
}
}
}
When i start() 5 Threads why just first one pop all elements and others do not pop anyone?
I tried to use wait() and notify() methods, but that didn't help..
The method yield does not release locks. The very first thread that enters the synchronized block will keep other threads from entering until the stack is empty and the lock is released.
Here is an example that does what you want using LinkedBlockingDeque.
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.LinkedBlockingDeque;
class Main {
static final LinkedBlockingDeque<Integer> stack = new LinkedBlockingDeque<>();
static class Poller implements Runnable {
final Set<Integer> set = new HashSet<>();
#Override
public void run() {
Integer elem = stack.poll();
while (elem != null) {
set.add(elem);
System.out.printf("%s: %d\n", Thread.currentThread().getName(), elem);
elem = stack.poll();
}
}
}
public static void main(String args[]) {
for (int i = 0; i < 100; i++) {
stack.push(i);
}
for (int i = 0; i < 5; i++) {
new Thread(new Poller()).start();
}
}
}
Related
ProdCom.java (driver class)
import static java.lang.System.out;
public class ProdCom{
static int full = 50;
static int mutx = 0;
static int empty = 0;
static int currentSize = 0;
public static void acquire(){
while (mutx == 1);
mutx++;
}
public static void release(){
mutx--;
}
public static void main(String args[]){
Thread t = new Thread(new Producerr());
Thread t1 = new Thread(new Consumerr());
t.start();
t1.start();
}
}
Producerr.java
class Producerr implements Runnable{
public void wwait(){
while (ProdCom.currentSize >= ProdCom.full){
}
} public void signal(){
ProdCom.currentSize++;
}
public void run(){
do{
this.wwait();
ProdCom.acquire();
out.println("Num elements" + ProdCom.currentSize);
out.println("producing!");
ProdCom.release();
this.signal();
} while (true);
}
}
Consumerr.java
class Consumerr implements Runnable{
public void wwait(){
while (ProdCom.currentSize <= 0){
out.println("inside consumer wait: ");
out.println("number of elements: " + ProdCom.currentSize);
}
} public void signal(){
ProdCom.currentSize--;
}
public void run(){
do{
this.wwait();
ProdCom.acquire();
out.println("Num elements" + ProdCom.currentSize);
out.println("Consuming!");
ProdCom.release();
this.signal();
} while (true);
}
}
Above is my solution to the consumer-producer problem. The driver class ProdCom has variables full, empty and mutx for controlling producer t and consumer t1's access to the variable currentSize (Thus simulating the current number of items in a buffer). But when I run the code, the output seems to indicate t1 and t aren't taking turns to change currentSize, instead one of them repeats forever and gets stuck...I'm wondering why? Thanks.
I've improved your code a bit, and you'll notice that many of the concepts mentioned by Joni are considered.
ProdCom.java
import java.lang.*;
public class ProdCom{
static final int FULL = 50;
static final int EMPTY = 0;
static volatile int mutx = 0;
static volatile int currentSize = 0;
static Object lockObject = new Object();
public static void acquire(){
/* since mutx is defined volatile, the spinlock works,
but you reconsider this approach. There are cheaper
methods of heating the room */
while (mutx == 1);
mutx++;
}
public static boolean isEmpty() {
synchronized(lockObject) {
if (currentSize <= EMPTY) return true;
return false;
}
}
public static boolean isFull() {
synchronized(lockObject) {
if (currentSize >= FULL) return true;
return false;
}
}
public static int getCurrentSize() {
synchronized(lockObject) {
return currentSize;
}
}
public static void release(){
mutx--;
}
public static void incCurrentSize()
{
synchronized(lockObject) {
currentSize++;
}
}
public static void decCurrentSize()
{
synchronized(lockObject) {
currentSize--;
}
}
public static void main(String args[]){
Thread t = new Thread(new Producerr());
Thread t1 = new Thread(new Consumerr());
t.start();
t1.start();
}
}
Consumerr.java
import java.lang.*;
class Consumerr implements Runnable {
public void wwait() {
while (ProdCom.isEmpty()){
System.out.println("inside consumer wait: ");
System.out.println("number of elements: " + ProdCom.getCurrentSize());
try {
/* we don't spinlock here */
Thread.sleep(50);
} catch (Exception e) {
/* do nothing */
}
}
}
public void signal(){
ProdCom.decCurrentSize();
}
public void run(){
do{
this.wwait();
ProdCom.acquire();
System.out.println("Num elements " + ProdCom.getCurrentSize());
System.out.println("Consuming!");
this.signal();
ProdCom.release();
} while (true);
}
}
Producerr.java
import java.lang.*;
class Producerr implements Runnable {
public void wwait(){
while (ProdCom.isFull()){
try {
Thread.sleep(50);
} catch(Exception e) { /* do nothing */ }
}
}
public void signal(){
ProdCom.incCurrentSize();
}
public void run(){
do {
this.wwait();
ProdCom.acquire();
System.out.println("Num elements : " + ProdCom.getCurrentSize());
System.out.println("producing!");
this.signal();
ProdCom.release();
} while (true);
}
}
The Java memory models allows threads to cache the values of variables, and different threads to have different caches. This means that the spin lock in acquire easily becomes an infinite loop: the thread in acquire may use the cached value mutx = 1 and never read the updated value from main memory:
while (mutx == 1); // infinite loop even if another thread changes mutx
Another problem is that the ++ and -- operators are not atomic: they read the value of the variable, modify it, and write it back. If two threads run currentSize++ and currentSize-- at the same time it is possible one of them is lost.
You can fix these problems by using an AtomicInteger object and its methods instead of int, for example in ProdCom:
static AtomicInteger currentSize = new AtomicInteger(0);
static AtomicInteger mutx = new AtomicInteger(0);
public static void acquire() {
while (!mutx.compareAndSet(0, 1));
}
public static void release() {
mutx.set(0);
}
I'd like to set parameter on Runnable then get value.
I wrote this code. When I run this code return [2, 3, 3]. Because the thread share temp_value.
Then I added sleep which was comment outed. The result is [1, 2, 3]. It works fine!! But.. it is not real multithread, right?
Even it's running multithread, but I need wait the each process finish for the shared value.
How can solve this problem?
import java.util.ArrayList;
public class Foo implements Runnable {
private int temp_value;
private ArrayList<Integer> values = new ArrayList<Integer>();
private ArrayList<Integer> newValues = new ArrayList<Integer>();
public Foo(ArrayList<Integer> values) {
this.values = values;
}
public static void main(String[] args) {
// make initial values
ArrayList<Integer> values = new ArrayList<Integer>();
values.add(1);
values.add(2);
values.add(3);
// set values then process and get new values
Foo foo = new Foo(values);
foo.startAppendValue(foo);
System.out.println(foo.getNewValues());
}
public void startAppendValue(Foo foo) {
Thread thread = null;
int max = values.size();
for (int i = 0; i < max; i++) {
foo.temp_value =foo.values.get(i);
thread = new Thread(foo);
thread.start();
// try {
// Thread.sleep(10);
// } catch (Exception e) {
// // TODO: handle exception
// }
}
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
#Override
public void run() {
newValues.add(temp_value);
}
public ArrayList<Integer> getNewValues() {
return this.newValues;
}
}
You can use Callable and ExecutorService to do the stuff
public class MyCallable implements Callable<Integer> { //Callable is like Runnable but can return value
private Integer value;
public MyCallable(Integer v) {
value = v;
}
public Integer call() {
return value;
}
public static void main(String[] args) {
ExecutorService exec = Executors.newFixedThreadPool(3); //Creating thread pool with 3 worker threads
List<Integer> values = Arrays.asList(1, 2, 3);
List<Future<Integer>> futures = new ArrayList<>(values.size());
List<Integer> newValues = new ArrayList<>(values.size());
for (Integer v : values) {
futures.add(exec.submit(new MyCallable(v))); //Submit tasks to worker threads to do stuff in background
}
for (Future<Integer> f : futures) {
try {
newValues.add(f.get()); // get calculated result from worker thread or block waiting for result to become available
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
System.out.println(newValues);
exec.shutdownNow();
}
}
I would use a List.parallelStream()
public class Foo {
public static void main(String[] args) {
// make initial values
List<Integer> values = new ArrayList<Integer>();
values.add(1);
values.add(2);
values.add(3);
// process each value using multiple threads.
List<Integer> results = values.parallelStream()
.map(Foo::processValue)
.collect(Collectors.toList());
}
static Integer processValue(Integer i) {
// do something interesting
return i;
}
}
Even it's running multithread, but I need wait the each process finish for the shared value.
Correct, you need to make sure.
each thread has it's only copy of the data.
shared collections are accessed in a thread safe manner.
I tried writing this with Threads but it's far too painful to post here.
i think your shared data makes mistake. for this keep i in private space. you can have class like this:
remove temp_value from Foo class and move runnable part to new class named PV.
Class PV implements Runnable{
int index;
Foo foo;
PV(int index,Foo foo){
this.index = index;
this.foo = foo;
}
}
#Override
public void run() {
this.foo.newValues.add(foo.values.get(index));
}
}
PV[] pvArr = new PV[max];
for (int i = 0; i < max; i++) {
pvArr[i] = new PV(i,foo);
foo.temp_value =foo.values.get(i);
thread = new Thread(pvArr[i]);
thread.start();
As mentioned by Java_author:
5.1.1. Problems with Synchronized Collections
The synchronized collections are thread-safe, but you may sometimes need to use additional client-side locking to guard compound actions.
Example - Multiple producer/consumer problem:
Algorithm using busy wait approach for multiple producers consumers working on thread-unsafe buffer, requires,
global RingBuffer queue; // A thread-unsafe ring-buffer of tasks.
global Lock queueLock; // A mutex for the ring-buffer of tasks.
But below code runs busy wait(while(true){..}) algorithm using thread safe buffer(queue), without a lock,
/* NumbersProducer.java */
package responsive.blocking.prodcons;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadLocalRandom;
public class NumbersProducer implements Runnable{
private BlockingQueue<Integer> numbersQueue;
private final int poisonPill;
private final int poisonPillPerProducer;
public NumbersProducer(BlockingQueue<Integer> numbersQueue, int poisonPill, int poisonPillPerProducer) {
this.numbersQueue = numbersQueue;
this.poisonPill = poisonPill;
this.poisonPillPerProducer = poisonPillPerProducer;
}
#Override
public void run() {
try {
generateNumbers();
}catch(InterruptedException e) {
Thread.currentThread().interrupt();
}
}
private void generateNumbers() throws InterruptedException{
for(int i=0; i < 100; i++) {
numbersQueue.put(ThreadLocalRandom.current().nextInt(100));
}
for(int j=0; j < poisonPillPerProducer; j++) {
numbersQueue.put(poisonPill);
}
}
}
/* NumbersConsumer.java */
package responsive.blocking.prodcons;
import java.util.concurrent.BlockingQueue;
public class NumbersConsumer implements Runnable{
private BlockingQueue<Integer> queue;
private final int poisonPill;
public NumbersConsumer(BlockingQueue<Integer> queue, int poisonPill) {
this.queue = queue;
this.poisonPill = poisonPill;
}
public void run() {
try {
while(true) {
Integer number = queue.take();
if(number.equals(poisonPill)) {
return;
}
System.out.println(Thread.currentThread().getName() + " result: " + number);
}
}catch(InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
/* Driver.java */
package responsive.blocking.prodcons;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class Driver {
public static void main(String[] args) {
int BOUND = 10;
int nProducers = 4;
int nConsumers = Runtime.getRuntime().availableProcessors();
int poisonPill = Integer.MAX_VALUE;
int value = 1;
int poisonPillPerProducer = ((value = nConsumers / nProducers) < 1)?1:value;
BlockingQueue<Integer> queue = new LinkedBlockingQueue<>(BOUND);
for(int i =0; i< nProducers; i++) {
new Thread(new NumbersProducer(queue, poisonPill, poisonPillPerProducer)).start();
}
for(int j=0;j < nConsumers; j++ ) {
new Thread(new NumbersConsumer(queue, poisonPill)).start();
}
}
}
Question:
In the above code,
How do I assess the need of additional client-side locking? Key is compound actions...
I have a program where 3 Threads are trying to print numbers in sequence from 1 to 10. I am using a CountDownLatch to keep keep a count.
But the program stops just after printing 1.
Note: I am aware that using AtomicInteger instead of Integer can work. But I am looking to find out the issue in the current code.
public class Worker implements Runnable {
private int id;
private volatile Integer count;
private CountDownLatch latch;
public Worker(int id, Integer count, CountDownLatch latch) {
this.id = id;
this.count = count;
this.latch = latch;
}
#Override
public void run() {
while (count <= 10) {
synchronized (latch) {
if (count % 3 == id) {
System.out.println("Thread: " + id + ":" + count);
count++;
latch.countDown();
}
}
}
}
}
Main program:
public class ThreadSequence {
private static CountDownLatch latch = new CountDownLatch(10);
private volatile static Integer count = 0;
public static void main(String[] args) {
Thread t1 = new Thread(new Worker(0, count, latch));
Thread t2 = new Thread(new Worker(1, count, latch));
Thread t3 = new Thread(new Worker(2, count, latch));
t1.start();
t2.start();
t3.start();
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Edited program with AtomicInteger:
public class ThreadSequence {
private static AtomicInteger atomicInteger = new AtomicInteger(1);
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new WorkerThread(0, atomicInteger));
Thread t2 = new Thread(new WorkerThread(1, atomicInteger));
Thread t3 = new Thread(new WorkerThread(2, atomicInteger));
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
System.out.println("Done with main");
}
}
public class WorkerThread implements Runnable {
private int id;
private AtomicInteger atomicInteger;
public WorkerThread(int id, AtomicInteger atomicInteger) {
this.id = id;
this.atomicInteger = atomicInteger;
}
#Override
public void run() {
while (atomicInteger.get() < 10) {
synchronized (atomicInteger) {
if (atomicInteger.get() % 3 == id) {
System.out.println("Thread:" + id + " = " + atomicInteger);
atomicInteger.incrementAndGet();
}
}
}
}
}
But the program stops just after printing 1.
No this is not what happens. None of the threads terminate.
You have a own count field in every worker. Other threads do not write to this field.
Therefore there is only one thread, where if (count % 3 == id) { yields true, which is the one with id = 0. Also this is the only thread that ever modifies the count field and modifying it causes (count % 3 == id) to yield false in subsequent loop iterations, causing an infinite loop in all 3 threads.
Change count to static to fix this.
Edit
In contrast to Integer AtomicInteger is mutable. It is a class that holds a int value that can be modified. Using Integer every modification of the field replaces it's value, but using AtomicInteger you only modify the value inside the AtomicInteger object, but all 3 threads continue using the same AtomicInteger instance.
Your "count" is a different variable for each thread, so changing it in one thread doesn't affect the rest, and so they are all waiting for it to change, without any one that can do it.
Keep the count as static member in Worker class - common for all object in the class.
You can use below code to print sequential numbers using multiple threads -
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class ThreadCall extends Thread {
private BlockingQueue<Integer> bq = new ArrayBlockingQueue<Integer>(10);
private ThreadCall next;
public void setNext(ThreadCall t) {
this.next = t;
}
public void addElBQ(int a) {
this.bq.add(a);
}
public ThreadCall(String name) {
this.setName(name);
}
#Override
public void run() {
int x = 0;
while(true) {
try {
x = 0;
x = bq.take();
if (x!=0) {
System.out.println(Thread.currentThread().getName() + " =>" + x);
if (x >= 100) System.exit(0); // Need to stop all running threads
next.addElBQ(x+1);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
int THREAD_COUNT = 10;
List<ThreadCall> listThread = new ArrayList<>();
for (int i=1; i<=THREAD_COUNT; i++) {
listThread.add(new ThreadCall("Thread " + i));
}
for (int i = 0; i < listThread.size(); i++) {
if (i == listThread.size()-1) {
listThread.get(i).setNext(listThread.get(0));
}
else listThread.get(i).setNext(listThread.get(i+1));
}
listThread.get(0).addElBQ(1);
for (int i = 0; i < listThread.size(); i++) {
listThread.get(i).start();
}
}
}
I hope this will resolve your problem
I have two classes, main and timex. I want to display the value of a variable in my timex class, but I always get the answer 0.
public class mainaxe {
public static void main (String arg[]) {
timex n = new timex();
int n2 = timex.a;
n.timedel();
for(int i=0; i<20; i++) {
System.out.println("the time is :" + n2);
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {}
}
}
}
And this is my timex class:
public class timex extends Thread{
public static int a;
public int timedel(){
for(int i=0; i<200; i++) {
try {
Thread.sleep(1000);
a = a + 5;
}
catch (InterruptedException e){}
// start();
}
return a;
}
}
I want to get the value from the timex class and use it in my main class to print the value for every 1 sec.
I guess you need something like,
Mainaxe.java
package mainaxe;
public class Mainaxe {
public static void main(String arg[]) {
Timex n = new Timex();
n.start();
// int n2 = Timex.a;
// n.timedel();
for (int i = 0; i < 20; i++) {
System.out.println("the time is :" + Timex.a);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
}
}
Timex.java
package mainaxe;
public class Timex extends Thread {
public static int a;
public Timex() {
super();
}
#Override
public void run() {
timedel();
}
public int timedel() {
for (int i = 0; i < 200; i++) {
try {
Thread.sleep(1000);
a = a + 5;
} catch (InterruptedException e) {
}
// start();
}
return a;
}
}
If you want a multi-threaded program, then in your class that extends Thread, declare a method exactly like this:
#Override
public void run () {
// in here, put the code your other thread will run
}
Now, after you create a new object of this class:
timex n = new timex();
you have to start the thread like this:
n.start();
This causes the object to start running its run method in a new thread. Having your main thread call other methods in n won't do anything with the new thread; any other method called by the main thread will be performed in the main thread. So you can't communicate with the new thread with a function call. You have to do it with other means, such as you were trying to do with your variable a.