The program's aim is to simulate that multiple users add a number to the buffer from 0 to n. Then print the sum of numbers in the buffer. When I run the program, it seems that the threads never end. However, the thread will finish when I run the program in debug mode of Idea and step line by line. Also, I do not exactly know where I need to use my semaphore method P() and V() for mutual exclusion.
Version: JDK 8. I cannot use semaphore in the library.
Main.java
Buffer b = new Buffer(bufferSize);
ArrayList<user> us = new ArrayList<>();
for(int i = 0; i < num_users; i++) us.add(new user(i, elements, b));
ArrayList<Thread> th = new ArrayList<>();
for(int i = 0; i < num_users; i++)
{
th.add(new Thread(us.get(i)));
th.get(i).start();
}
user.java
public class user implements Runnable
{
private int id;
private int num_elements;
private semaphore mutex = new semaphore(1 );
public static Buffer buf;
public user(int i, int el, Buffer b)
{id = i; num_elements = el; buf = b;}
public void add_elements()
{//Add element to buffer, element value iterates from 0, 1, 2 .... num_elements
mutex.P();
int n = 0;
while (num_elements > 0)
{
buf.add(new Integer(n));
n++;
num_elements--;
}
mutex.V();
}
public void run()
{
add_elements();
}
}
Buffer.java
public class Buffer
{
private LinkedList<Object> buf_list;
private int elements; //Number of elements currently on the queue
private int buf_size; //Maximum number of elements allowed on queue
private semaphore mutex = new semaphore(1);
public Buffer(int n) //Queue creation, with n indicating the maximum capacity
{
buf_list = new LinkedList<Object>();
elements = 0;
buf_size = n;
}
public void add(Integer n)
{
mutex.P();
buf_list.add(n);
elements++;
mutex.V();
}
public void finalSummation()
{
if (elements == buf_size)
{
mutex.P();
int sum = 0;
for (Object n : buf_list)
sum += ((Integer)n).intValue();
mutex.V();
System.out.println("Count total: " + sum);
}
}
}
semaphore.java
public class semaphore
{
private int count = 0;
public semaphore(int init_count)
{
count = init_count;
}
public synchronized void P()
{
count -= 1;
while (count < 0)
{
try {
wait();
} catch (InterruptedException e) {
System.out.println("Error");
System.exit(-1);
}
}
}
public synchronized void V()
{
count += 1;
notifyAll();
}
}
I expect it will print the sum of buffer numbers, but the thread may not finish.
There are a few things that stand out as issues here.
1) your code is never calling the finalSummation method. So the "printing" of the result will never happen.
2) Buffer and each user are all creating their own semaphores. If you are attempting to allow multiple threads to update Buffer without colliding then you need to share the same semaphore. Remove the semaphore and the usage of it from the user class. Just let the Buffer instance control only one update at a time with its semaphore.
3) You don't need to check the semaphore in the finalSummation method. Presumably, all threads are done at that point. And to enforce that ...
4) Put code like this at the end of main
for(int i = 0; i < num_users; i++) {
th.get(i).join();
}
b.finalSummation();
5) A semaphore should manage a number of permits. Your semaphore is managing the number of instances waiting - that is a pretty much an irrelevant number for a semaphore. Change your P() and V() to acquire() and release() to be consistent with the pattern.
public static class semaphore {
private int permits = 0;
public semaphore(int permits) {
this.permits = permits;
}
public synchronized void acquire() {
while (permits < 1) {
try {
wait();
} catch (InterruptedException e) {
System.out.println("Error");
System.exit(-1);
}
}
permits--;
}
public void release() {
synchronized (this) {
permits += 1;
notifyAll();
}
}
}
I have put it together using the above answer if that helps. Please select above answer as the right answer.
import java.util.ArrayList;
import java.util.LinkedList;
public class Main {
// assumed values
private static final int bufferSize = 5;
private static final int num_users = 10;
private static final int elements = 5;
public static void main(String[] args) {
Buffer b = new Buffer(bufferSize);
ArrayList<User> us = new ArrayList<>();
for(int i = 0; i < num_users; i++) us.add(new User(i, elements, b));
ArrayList<Thread> th = new ArrayList<>();
for(int i = 0; i < num_users; i++)
{
th.add(new Thread(us.get(i)));
th.get(i).start();
}
for(int i = 0; i < num_users; i++) {
try {
th.get(i).join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
b.finalSummation();
System.out.println("Exiting");
}
}
class User implements Runnable
{
private int id;
private int num_elements;
public static Buffer buf;
public User(int i, int el, Buffer b)
{id = i; num_elements = el; buf = b;}
public void add_elements()
{//Add element to buffer, element value iterates from 0, 1, 2 .... num_elements
int n = 0;
while (num_elements > 0)
{
buf.add(new Integer(n));
n++;
num_elements--;
}
}
public void run()
{
add_elements();
}
}
class Buffer
{
private LinkedList<Object> buf_list;
private int elements; //Number of elements currently on the queue
private int buf_size; //Maximum number of elements allowed on queue
private Semaphore mutex ;
public Buffer(int n) //Queue creation, with n indicating the maximum capacity
{
buf_list = new LinkedList<Object>();
elements = 0;
buf_size = n;
mutex = new Semaphore(buf_size);
}
public synchronized void add(Integer n)
{
mutex.acquire();
buf_list.add(n);
elements++;
mutex.release();
}
public void finalSummation()
{
int sum = 0;
System.out.println(buf_list);
for (Object n : buf_list)
sum += ((Integer)n).intValue();
System.out.println("Count total: " + sum);
}
}
class Semaphore {
private int permits = 0;
public Semaphore(int permits) {
this.permits = permits;
}
public synchronized void acquire() {
while (permits < 1) {
try {
wait();
} catch (InterruptedException e) {
System.out.println("Error");
System.exit(-1);
}
}
permits--;
}
public void release() {
synchronized (this) {
permits += 1;
notifyAll();
}
}
}
Related
To understand the concept of threads better, we are supposed to use a Number object that can be increased, decreased, squared and rooted via it's methods. It's only attribute is a double number (initialized as number=1).
So if i instantiate the Number object and call increment(), decrement(), square() and root() 100000000 times to that number object, the number attribute is 1 again (as expected).
Now the problem is that we are supposed to instantiate two thread objects, one calling the increase/decrease 100000000 times and the other one calling square/root 100000000 times.
According to our teacher the result would be inconsistency, i.E getting 0 instead of 1 as the result, but in my program it just gives me infinity or 1 depending on wether or not i am using synchronized() in the Thread class.
public class Calculation {
public static void main(String[] args) throws InterruptedException {
Number num = new Number();
Number num1 = new Number();
for (int i = 0; i < 100000000; i++) {
num.increment();
}
for (int i = 0; i < 100000000; i++) {
num.decrement();
}
for (int i = 0; i < 100000000; i++) {
num.square();
}
for (int i = 0; i < 100000000; i++) {
num.root();
}
System.out.println(num.getNumber());
CalcThread t1 = new CalcThread(num1, true);
CalcThread t2 = new CalcThread(num1, false);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(num1.getNumber());
}
}
public class CalcThread extends Thread {
public Number num;
public boolean decision;
public CalcThread(Number num, boolean decision) {
this.num = num;
this.decision = decision;
}
#Override
public void run() {
synchronized(num) {
if (this.decision) {
for (int i = 0; i < 100000000; i++) {
num.square();
}
for (int i = 0; i < 100000000; i++) {
num.root();
}
} else {
for (int i = 0; i < 100000000; i++) {
num.increment();
}
for (int i = 0; i < 100000000; i++) {
num.decrement();
}
}
}
}
}
public class Number {
double number;
public Number() {
this.number = 1;
}
public void increment() {
this.number++;
}
public void decrement() {
this.number--;
}
public void square() {
this.number = this.number * this.number;
}
public void root() {
this.number = Math.sqrt(this.number);
}
public double getNumber() {
return number;
}
public void setNumber(double number) {
this.number = number;
}
}
Getting infinity when leaving synchronized out makes sense because it is increasing while squaring the number at the same time, so the number will soon be too large to fit the double type size right?
How do i get the inconsistency my teacher was talking about?
Thank you for your help in advance.
I will input some number to calculates sum of Factorial series,
like if i put 5, output will be 1!+2!+3!+4!+5!, but calculating processing could be heavy so i want to use multiple treads that calculates each factorial.. means thread1 cals 1!, thread2 cals 2!...
i used arrays of threads but can't sync them in propel results. and can't find the way to sum these results.
i wrote codes...
public class Calthread extends Thread{
private int num=1;
public Calthread(int num) {
this.num = num;
}
public void run() {
int dft = 1;
for(int i=1; i<=num; i++) {
dft = dft*i;
}
System.out.println(num + "! result :" + dft);
}
}
this is for 1 thread
for main class
public class calculator {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("input number>>");
int k = scanner.nextInt(); //input 'k'
int sum = 0;
Calthread[] cal = new Calthread[k]; // make threads number of 'k'
for(int i = 0; i<k; i++) {
cal[i] = new Calthread(i+1);
cal[i].start();
}
}
}
how can I Sync them and print the sum of all?
To return value from thread you should use Callable instead of Runnable:
public class Calthread implements Callable<Integer> {
private int num = 1;
public Calthread(int num) {
this.num = num;
}
#Override
public Integer call() {
int dft = 1;
for (int i = 1; i <= num; i++) {
dft = dft * i;
}
return dft;
}
}
And in the main class:
public class Calculator {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("input number>>");
int k = scanner.nextInt(); //input 'k'
int sum = 0;
// Make threads number of 'k'. Here we use List instead of array because there is such contract in ExecutorService
List<Calthread> cal = new ArrayList<>(k);
// Create thread pool with fixed number of threads
ExecutorService service = Executors.newFixedThreadPool(k);
// Add all Callable task in one collection
for (int i = 0; i < k; i++) {
cal.add(new Calthread(i+1));
}
try {
// Invoke all Callable task and get List with results
List<Future<Integer>> results = service.invokeAll(cal);
// Future::get is blocking method. It waits result.
for (Future<Integer> result : results) {
sum += result.get();
}
} catch (InterruptedException | ExecutionException e) {
System.out.println("Something went wrong");
e.printStackTrace();
}
System.out.println("Result: " + sum);
// We need to shutdown our service
service.shutdown();
}
}
I know I can use callables to get a return value but is it possible to solve this without using it?
I am trying to get the tempCounter value from the primeThread and add them all into the counter. But I received a "symbol not found" error.
Is it possible for me the call the runnable method from the arrayList in the PrimeCounter class?
public class PrimeCounter {
public static void countPrimes() {
int counter = 0;
int primeNumbers = 2_534_111;
final int NUM_OF_THREAD = 4;
int startRange = 2;
int range = primeNumbers / NUM_OF_THREAD;
int endRange = startRange + range;
ArrayList<Thread> threadList = new ArrayList<Thread>();
for (int i = 0; i < NUM_OF_THREAD; i++) {
threadList.add(new Thread(new primeThread(startRange, endRange)));
startRange += range;
if (endRange + range < primeNumbers) {
endRange += range;
} else {
endRange = primeNumbers;
}
}
for (Thread t : threadList) {
t.start();
try {
t.join();
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
}
for (int i = 0; i < threadList.size(); i++) {
Thread tempThread = threadList.get(i);
while (tempThread.isAlive()) {
counter += tempThread.getCounter(); // symbol not found
}
}
System.out.println("\nNumber of identified primes from 2 to " + primeNumbers + " is :" + counter);
}
// checks if n is a prime number. returns true if so, false otherwise
public static boolean isPrime(long n) {
//check if n is a multiple of 2
if (n % 2 == 0) {
return false;
}
//if not, then just check the odds
for (long i = 3; i * i <= n; i += 2) {
if (n % i == 0) {
return false;
}
}
return true;
}
primeThread Runnable
class primeThread implements Runnable {
private int startRange;
private int endRange;
private int threadCounter = 0;
public primeThread(int startRange, int endRange) {
this.startRange = startRange;
this.endRange = endRange;
}
#Override
public void run() {
for (int i = startRange; i < endRange; i++) {
if (Dumb.isPrime(i)) {
threadCounter++;
}
}
}
public int getCounter() {
return threadCounter;
}
First of all read about Java naming convention (your class names did't meet the convention)
With this fragment you say every thread to start, and before next tread to start main thread to wait the termination of this thread(Do you really want this?):
for (Thread t : threadList) {
t.start();
try {
t.join();
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
}
Finally you get a thread from arrayList and you try to run a method that this thread don't have.
for (int i = 0; i < threadList.size(); i++) {
Thread tempThread = threadList.get(i);
while (tempThread.isAlive()) {
counter += tempThread.getCounter(); // symbol not found
}
}
getCounter is method for primeThread class, but you have Thread class!
You can fix this problem if your class primeThread extends Thread class.
I want to generate pairs from a given large pool of numbers. I am using two for loops and threads. My function getAllPairs() in the code generates apairs with a given array of numbers.
I have an array of length 1000. With one thread, output time is nearly 15 sec. Now I want to use 5-6 threads and reduce this output time.I am stuck at dividing this task equally to five threads.If not threads,how to decrease the output time?
Solution with threads is appreciated since I put a lot of time learning multithreading. I would like to implement it.
import java.util.*;
class Pair {
public int x, y;
public Pair(int x, int y) {
this.x = x;
this.y = y;
}
#Override
public String toString(){
return " ( " + x + " ," + y + " ) " ;
}
}
class selectPairs{
private int[] array;
private List<Pair> totalPairs ;
public selectPairs(int[] arr){
array = arr;
}
//set Method
public void settotalPairs(List<Pair> pieces){
totalPairs = pieces;
}
//get Method
public List<Pair> gettotalPairs(){
return totalPairs;
}
// Method to generate pairs
public List<Pair> getAllPairs() {
List<Pair> pairs = new ArrayList<Pair>();
int total = array.length;
for(int i=0; i < total; i++) {
int num1 = array[i];
for(int j=i+1; j < total; j++) {
int num2 = array[j];
pairs.add(new Pair(num1,num2));
}
}
return pairs;
}
}
// Thread class
class ThreadPairs extends Thread {
private Thread t;
selectPairs SP;
ThreadPairs(selectPairs sp){
SP = sp;
}
public void run() {
synchronized(SP) {
List<Pair> PAIRS = SP.getAllPairs();
SP.settotalPairs(PAIRS);
}
}
}
public class TestThread {
public static void main(String args[]) {
int[] a = new int[1000];
for (int i = 0; i < a.length; i++) {
a[i] = i ;
}
selectPairs ob = new selectPairs(a);
ThreadPairs T = new ThreadPairs( ob );
T.start();
while (true) {
try {
T.join();
break;
}
catch(Exception e){
}
}
List<Pair> Total = new ArrayList<Pair>() ;
List<Pair> Temp1 = ob.gettotalPairs();
Total.addAll(Temp1);
System.out.println(Total);
}
}
A solution with a thread-pool, a task split strategy and it collects all results:
public class SelectPairs {
private static final int NUM_THREADS = 8;
private int[] array;
public SelectPairs(int[] arr) {
array = arr;
}
// A splitting task strategy
public List<Pair> getPartialPairs(int threadIndex, int numThreads) {
List<Pair> pairs = new ArrayList<Pair>();
int total = array.length;
for (int i = threadIndex; i < total; i += numThreads) {
int num1 = array[i];
for (int j = i + 1; j < total; j++) {
int num2 = array[j];
pairs.add(new Pair(num1, num2));
}
}
return pairs;
}
// To use Callables or Runnables are better than extends a Thread.
public static class PartialPairsCall implements Callable<List<Pair>> {
private int thread;
private int totalThreads;
private SelectPairs selectPairs;
public PartialPairsCall(int thread, int totalThreads, SelectPairs selectPairs) {
this.thread = thread;
this.totalThreads = totalThreads;
this.selectPairs = selectPairs;
}
#Override
public List<Pair> call() throws Exception {
return selectPairs.getPartialPairs(thread, totalThreads);
}
}
public static void main(String[] args) throws Exception {
int[] a = new int[1000];
for (int i = 0; i < a.length; i++) {
a[i] = i;
}
SelectPairs sp = new SelectPairs(a);
// Create a thread pool
ExecutorService es = Executors.newFixedThreadPool(NUM_THREADS);
List<Future<List<Pair>>> futures = new ArrayList<>(NUM_THREADS);
// Submit task to every thread:
for (int i = 0; i < NUM_THREADS; i++) {
futures.add(es.submit(new PartialPairsCall(i, NUM_THREADS, sp)));
}
// Collect the results:
List<Pair> result = new ArrayList<>(a.length * (a.length - 1));
for (Future<List<Pair>> future : futures) {
result.addAll(future.get());
}
// Shutdown thread pool
es.shutdown();
System.out.println("result: " + result.size());
}
}
regarding the framework of multithreading, you can implement ThreadPoolExecutor as was suggested in a comment.
Regarding splitting the workload, it seems that the key is splitting the iteration on the array which is achievable if you give the Runnable task a start and end index to iterate over.
I'm trying to implement a solution to the Dinning Philosophers. Not sure if I'm doing it right. My program isn't crashing but I am getting red text in the output, but there's no error code.
Example of the error:
at (package_name).Phil.getrightFork(Phil.java:70)
the error alternatives between line 70, and 46 (which is the line that calls getrightFork)
I've already swapping getrightFork with getleftFork, but it always selects the rightFork as the error
Here's the code I'm using:
Custom Semaphore:
public class Semaphore {
public int value= 0 ;
public Semaphore(int value) {
this.value = value;
}
public synchronized void up() { //notify must be syncrhonized
value++;
if (value > 0){
this.notifyAll();
}
}
public synchronized void down() throws InterruptedException {
while (value <= 0){//Check if resource is avaiable, if not WAIT.
this.wait();
}
value--; // Value is no longer negative
}}
main:
public class main {
private static final int N = 10000;
public static void main(String[] args) throws InterruptedException{
Phil[] phils = new Phil[N];
Semaphore[] forks = new Semaphore[N];
for (int i=0;i<N;i++){
forks[i] = new Semaphore(1);
phils[i] = new Phil(i, forks, N);
phils[i].start();
}
for (int i=0;i<N;i++){
phils[i].join();
}
}}
Phil class:
public class Phil extends Thread {
Semaphore fork[];
int phil, total, left, right;
boolean leftFork = false, rightFork = false;
public Phil(int spot ,Semaphore[] s, int N){
phil = spot;
left = spot;
fork = s;
switch(spot){
case 0:
right = N-1;
break;
default:
right = spot - 1;
break;
}
}
public void run(){
System.out.println("I am Phil " + phil + " my left fork is " + left + " my right fork is " + right);
while(true){
try {
if (phil%2 == 0){
Thread.sleep(10); // Let the odd Phils eat first
}
getrightFork();
if (rightFork){
getleftFork();
}
if (leftFork && rightFork){
eat();
retleftFork();
retrightFork();
}
Thread.sleep(10);
} catch (InterruptedException ex) {
}
}
}
void getleftFork() throws InterruptedException{
fork[left].down();
//System.out.println("I got my left fork!");
leftFork = true;
}
void getrightFork() throws InterruptedException{
fork[right].down();
//System.out.println("I got my right fork!");
rightFork = true;
}
void retleftFork(){
fork[left].up();
leftFork = false;
}
void retrightFork(){
fork[right].up();
rightFork = false;
}
void eat(){
System.out.println("Phil:" + phil + " ate");
}}
You're getting a NullPointerException. The element in the array you are trying to access is null.
This is caused by the fact that you start your Phil before the entire array is complete...
Phil[] phils = new Phil[N];
Semaphore[] forks = new Semaphore[N];
for (int i = 0; i < N; i++) {
forks[i] = new Semaphore(1);
phils[i] = new Phil(i, forks, N);
// Phil is starting, but how many phils are there??
phil.start();
}
Instead, try filling the array first and then starting them in a separate loop...
Phil[] phils = new Phil[N];
Semaphore[] forks = new Semaphore[N];
for (int i = 0; i < N; i++) {
forks[i] = new Semaphore(1);
phils[i] = new Phil(i, forks, N);
}
for (Phil phil : phils) {
phil.start();
}
for (int i = 0; i < N; i++) {
phils[i].join();
}
If the solution requires that Phil be started as soon as they are created, then you need to change you checking code to handle the situation that the next element may be null