I'm new to multithreading. I need to calculate integral by partial sums using multiple threads. I want to find out if all threads finished calculating to show general sum, I'm doing it using sleep(500) but it's stupid. How can i do it by the right way?
public class MainClass {
private static int threadCount=10;
public static double generalSum=0;
private static ArrayList<CalculatingThread> threads;
public static void main(String[] args){
Calculator.setA(0);
Calculator.setB(2);
Calculator.setN(500);
threads=new ArrayList<CalculatingThread>();
int div=500/threadCount;
for (int i=0; i<div;i++){
CalculatingThread thread=new CalculatingThread();
thread.setJK(i*10,(i+1)*10-1);
thread.start();
threads.add(thread);
}
try {
Thread.currentThread().sleep(500);
System.out.println(generalSum);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class CalculatingThread extends Thread {
private int j;
private int k;
#Override
public void run(){
System.out.println("Partial sum: " + Calculator.calcIntegral(j, k));
Calculator.addToSumm(Calculator.calcIntegral(j, k));
//this.notify();
}
public void setJK(int j,int k) {
this.j = j;
this.k=k;
}
}
public class Calculator {
private static double a;
private static double b;
private static int n;
private static double InFunction(double x){
return Math.sin(x);
}
private double sum=0;
public static void setA(double a) {
Calculator.a = a;
}
public static void setB(double b) {
Calculator.b = b;
}
public static void setN(int n) {
Calculator.n = n;
}
public static double calcIntegral(int j,int k)
{
double result, h;
int i;
h = (b-a)/n; //Шаг сетки
result = 0;
for(i=j; i <= k; i++)
{
result += InFunction(a + h * i - h/2); //Вычисляем в средней точке и добавляем в сумму
}
result *= h;
return result;
}
public static synchronized void addToSumm(double sum){
MainClass.generalSum+=sum;
}
}
P.S. sorry, i know code is stupid, i will refactor it later
Replace
Thread.currentThread().sleep(500);
with
for (Thread thread : threads) {
thread.join();
}
This will make main thread to wait until all the created threads get completed. Also you can refer wait until all threads finish their work in java
you can use join to make the main thread wait for the others:
The join method allows one thread to wait for the completion of
another. If t is a Thread object whose thread is currently executing,
t.join(); causes the current thread to pause execution until t's
thread terminates. Overloads of join allow the programmer to specify a
waiting period. However, as with sleep, join is dependent on the OS
for timing, so you should not assume that join will wait exactly as
long as you specify.
save every thread you create in an array and then do join on them
so your main should look like
public class MainClass {
private static int threadCount=10;
public static double generalSum=0;
private static ArrayList<CalculatingThread> threads;
public static void main(String[] args){
Calculator.setA(0);
Calculator.setB(2);
Calculator.setN(500);
threads=new ArrayList<CalculatingThread>();
int div=500/threadCount;
for (int i=0; i<div;i++){
CalculatingThread thread=new CalculatingThread();
thread.setJK(i*10,(i+1)*10-1);
thread.start();
threads.add(thread);
}
try {
for (Thread curr: threads) {
curr.join();
}
System.out.println(generalSum);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
now on a side note, no series program is using sleep when it wants to wait. sleep is only used when you actually need a delay in a background thread
P.S.
do not refactor the code. it is excellent to post it like that, so i can see every mistake you do if u do. a lot better then most people posting only 1 line and then there is nothing i can do but ask for more details
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 have a problem where there is a BoundedBuffer and there are Consumers and Producers, the producers fill the buffer and consumers remove from the buffer.
I'm using threads for the Consumers and Producers, and i was trying to use lock conditions to ensure that the buffer isn't full to the producer and isn't empty for the consumer.
Unfortunately it's not working the way I wanted, it seems that the Consumer/Producer, when they are in Condition.await, don't let the other threads work. Shouldn't they let them?
Here is my code
class main
{
public static void main (String[] args) throws InterruptedException
{
final int N = Integer.parseInt(args[0]);
BoundedBuffer teste = new BoundedBuffer(N);
Thread c = new Consumidor(teste,N);
Thread p = new Produtor(teste,N);
c.start();
p.start();
c.join();
p.join();
}
}
class BoundedBuffer
{
ArrayList<Integer> array;
int index;
int size;
Lock l = new ReentrantLock();
Condition notFull = l.newCondition();
Condition notEmpty = l.newCondition();
BoundedBuffer(int N)
{
this.array=new ArrayList<Integer>(N);
this.index = 0;
this.size=N;
}
public synchronized void put(int e) throws InterruptedException
{
l.lock();
try
{
while(this.index >= this.size)
{
notFull.await();
}
this.array.add(index,e);
this.index++;
notEmpty.signal();
}
finally
{
l.unlock();
}
}
public synchronized int get() throws InterruptedException
{
int i;
l.lock();
try
{
while(this.index <=0)
{
notEmpty.await();
}
this.index--;
notFull.signal();
i = this.array.get(index);
}
finally
{
l.unlock();
}
return i;
}
}
class Consumidor extends Thread
{
private BoundedBuffer b;
final int j;
public Consumidor(BoundedBuffer b, int j)
{
this.b = b;
this.j=j;
}
public void run()
{
int a;
for (int i = 0; i < j ;++i)
{
try
{
a=b.get();
System.out.println("GET: " +a);
}
catch (Exception e) {}
}
}
}
class Produtor extends Thread
{
private BoundedBuffer b;
final int j;
public Produtor(BoundedBuffer b, int j)
{
this.b = b;
this.j=j;
}
public void run()
{
int a;
for (int i = 0; i < j; ++i)
{
try
{
b.put(i);
System.out.println("PUT: " +i);
}
catch (Exception e) {}
}
}
}
Thanks in advance
Don’t mix intrinsic locks (meaning synchronized) with reentrantLocks. This code is trying to acquire the intrinsic lock and then the reentrantlock.
Putting synchronized on an instance method requires the thread calling the method to acquire the intrinsic lock on the instance. ReentrantLock is a separate locking construct that does not use that keyword. Mixing the two mechanisms is unnecessary and can only cause trouble.
(Specifically the code is calling await on the condition object, which causes the thread to release the reentrant lock, but the thread keeps holding onto the intrinsic lock, preventing the other thread from entering a synchronized method.)
The fix for this is to delete the synchronized keyword from your code.
The goal: So I have a runnable class ThisThat. I instantiate two threads of ThisThat. One prints "This" and one prints "That". The main class is not supposed to determine what it prints.
The question: how do I make a default constructor set two different outputs for two threads of the same class? What can be improved? How can I make it only print this or that instead of both simultaneously?
Desired end result would be a program that runs for about 10 seconds and prints either this or that 10 times. Current output is "this" "that" at the same time, waits about 10 seconds and then repeats 10 times.
import java.util.Random;
public class ThisThat implements Runnable {
private String output;
private int threadNum;
public ThisThat() {
output = "";
}
public ThisThat(int t_Num) {
threadNum = t_Num;
setThisOrThat(threadNum);
}
public void setThisOrThat(int num) {
if (num == 1) {
output = "this";
} else if (num == 2) {
output = "that";
} else {
Random random = new Random();
int randNum = random.nextInt((3) + 1);
setThisOrThat(randNum);
}
}
#Override
public void run() {
for (int i=1; i <= 10; i++) {
try {
System.out.println(getOutput());
Thread.sleep((int)(800));
}
catch(InterruptedException e) {
System.err.println(e);
}
}
}
public String getOutput() { return output; }
public void setOutput(String output) { this.output = output; }
}
class Main {
public static void main(String args[]) {
Thread thread1 = new Thread(new ThisThat(1));
Thread thread2 = new Thread(new ThisThat(2));
thread1.start();
thread2.start();
}
}
One solution is to update the constructor to not take in anything from Main, then create a static volatile or Atomic property within your ThisThat class that is basically a counter changing the values for each thread instance.
Im trying to make 2 threads that read/write to a counter using thread safe methods.
I have written some code to try test this but the read thread just reads the counter at its max (1000)
Main:
public static void main(String[] args) {
Counter c = new Counter();
Thread inc = new Increment(c);
Thread read = new Read(c);
inc.start();
read.start();
}
Counter:
public class Counter {
private int count;
public Counter() {
count = 0;
}
public synchronized void increment() {
count++;
}
public synchronized int getVal() {
return count;
}
}
Increment:
public class Increment extends Thread {
private static final int MAX = 1000;
private Counter myCounter;
public Increment(Counter c) {
myCounter = c;
}
public void run() {
for (int i = 0; i < MAX; i++) {
myCounter.increment();
}
}
}
Read:
public class Read extends Thread {
private static final int MAX = 1000;
private Counter myCounter;
public Read(Counter c) {
myCounter = c;
}
public void run() {
for (int i = 0; i < MAX; i++) {
System.out.println(myCounter.getVal());
}
}
}
Would I be better off using Atomic Integer to hold the value of the counter to allow me to safely increment it and get the value?
Your code is perfectly fine as is. It just so happened that your increment thread finished all its increments before the read thread got a chance to read. 1,000 increments takes almost no time at all.
If you want interleave execution of Read thread and Increment thread much more often then the natural operating system thread pre-emption, just make each thread give up their lock (by calling <lockedObject>.wait() followed by <lockedObject>.notify() or notifyAll() in the respective run() methods:
[In Reader]:
public void run() {
for (int i = 0; i < MAX; i++) {
synchronized (myCounter) {
System.out.println(myCounter.getVal());
try {
myCounter.wait(0L, 1);
myCounter.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
[In Increment]:
public void run() {
for (int i = 0; i < MAX; i++) {
synchronized (myCounter) {
myCounter.increment();
try {
myCounter.wait(0L, 1);
myCounter.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Upping the MAX constant to 1_000_000_000 (1 billion) made the treads interleave as well every now and then (on my machine interleave happened just by gazing at few printouts between 150 and 400_000 iterations).
I'm a university student of Computer Science and I am familiar with threads in C.
However in Java the OOP makes Threads hard for me to understand.
I've written the following program and need to return values from the independent thread back to the main program.
The main program:
package main;
public class Main {
public static void main(String[] args) {
System.out.println(fibonacci(400));
}
public static int fibonacci(int x) {
Thread p1 = new Thread( new Fibonacci(x-1));
Thread p2 = new Thread( new Fibonacci(x-2));
p1.start();
p2.start();
int result = 0;
// Here I need the returns of the threads
// int result = thread_value1 + thread_value2;
return result;
}
}
The Fibonacci threads:
package main;
public class Fibonacci implements Runnable {
int result;
int x;
public Fibonacci(int parameter) {
x = parameter;
}
#Override
public void run() {
result = fib(x);
}
public int fib(int x) {
if(x == 1) return 1;
if(x == 2) return 1;
return fib(x-1) + fib(x-2);
}
}
The simplest way to achieve this is to save the results to a field in your Fibonacci objects and then read them from there. Note that since many threads will access this data, you need to synchronized access to these fields. In th e case of simple int values, adding the volatile modifier will be enough. It may also make the code clearer if you extend Thread instead of providing Runnable (but this is not neccessary). So your code could look something like this:
public class FibonacciThread extends Thread {
public volatile int result;
int x;
public FibonacciThread(int parameter) {
x = parameter;
}
#Override
public void run() {
result = fib(x);
}
public int fib(int x) {
if(x == 1) return 1;
if(x == 2) return 1;
return fib(x-1) + fib(x-2);
}
}
In main() you then do something like:
FibonacciThread p1 = new FibonacciThread(x-1);
FibonacciThread p2 = new FibonacciThread(x-2);
p1.start();
p2.start();
p1.join();
p2.join();
int result = p1.result + p2.result;
I'm skipping getters/setters and any fancy design for brevity's sake.
The call to Thread.join() is needed in order to wait for the thread to finish so that you can be sure that the result field was calculated before you read its value.
As noted by Sotirios Delimanolis in the comments, you can use Callable and ExecutorService for this, e.g. see this example
Another alternative that may be overkill here, but that is especially useful if the threads are producing more than one value, is to use a BlockingQueue or a ConcurrentLinkedQueue to communicate between threads. This is the basis behind libraries like Akka.
public class Main {
BlockingQueue<Integer> queue = new LinkedBlockingQueue();
public static int fibonacci(int x) {
Thread p1 = new Thread( new Fibonacci(x-1, queue));
Thread p2 = new Thread( new Fibonacci(x-2, queue));
p1.start();
p2.start();
// wait for queues to have values in them, then remove the values
int result = queue.take().intValue() + queue.take().intValue();
return result;
}
}
public class Fibonacci implements Runnable {
int x;
BlockingQueue<Integer> queue;
public Fibonacci(int parameter, BlockingQueue queueParam) {
x = parameter;
queue = queueParam;
}
#Override
public void run() {
// put output in queue
queue.offer(new Integer(fib(x)));
}
}