Print odd and even with 2 threads get wrong - java

I want to print odd and even from 0 to 1000, the simple code are as follow using wait(),notifyAll() and synchronized to lock this instance. But the result stops printing 0 and 1, I am confused by this, did I miss something or the synchronized key-word isn't used proper? Can someone explain this, I've trying to figure it out for several hours,yet get nothing...
public class Main {
public static void main(String[] args) {
final int count = 1000;
new Thread() {
public void run() {
for (int j = 0; j <= count; j = j + 2) {
synchronized (this) {
System.out.println("Even thread:\t" + j);
notifyAll();
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}.start();
new Thread() {
public void run() {
for (int j = 1; j <= count; j = j + 2)
synchronized (this) {
System.out.println("Odd thread:\t" + j);
notifyAll();
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
}
The result is:
Even thread: 0
Odd thread: 1
and the JVM is still running,But I want to print is "0 1 2 3 4 5....". I don't know why it's wrong.

Solved ,thank you!!!
Explain:
And key-word "this" should refer to a specific object, I thought it refers to the outer class instance for granted. And what I do is just create a Object instance called obj , and synchronized,wait, notifyAll with this "obj". Just a problem of reference. I feel I am a little dumb...
I found I can't accept my answer within 2 days:"accept × You can accept your own answer in 2 days"
public class Main {
public static void main(String[] args) {
//String obj="";
Object obj=new Object();
final int count = 1000;
new Thread() {
public void run() {
for (int j = 0; j <= count; j = j + 2) {
synchronized (obj) {
System.out.println("Even thread:\t" + j);
if(j==1000) System.exit(0);//exit the JVM when prints 1000
obj.notifyAll();
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}.start();
new Thread() {
public void run() {
for (int j = 1; j <= count; j = j + 2)
synchronized (obj) {
System.out.println("Odd thread:\t" + j);
obj.notifyAll();
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
}

Related

What is wrong with the my semaphore application?

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();
}
}
}

How do you print out the value you get from call() function in callable?

public double[] call() throws Exception {
int [] zero = {0,0};
double [] return_to_thread = { };
List<Integer> MyList = new ArrayList<Integer>();
for(int i = 0; i < N_W; i++) {
if(MyList.size() == n) {
N++;
}
MyList.clear();
int [] initial_point = {x,y};
for(int istep = 0; istep < n; istep++) {
randomWalk(initial_point);
if(!MyList.contains(computeHashCode(initial_point)) && !MyList.contains(computeHashCode(zero))) {
MyList.add(computeHashCode(initial_point));
} else {
break;
}
}
if(MyList.size() == n) {
end_to_end_dis_sq += Math.pow(initial_point[0], 2) + Math.pow(initial_point[1], 2);
}
}
return_to_thread[0] += N;
return_to_thread[1] += S;
// System.out.print(return_to_thread);
Thread.sleep(3000);
return return_to_thread;
}
The code above is the call() function that will return an array with double as the type.
public static void main(String [] args) {
ExecutorService service = Executors.newFixedThreadPool(1);
List<Future<double[]>> list = new ArrayList<Future<double[]>>();
Callable<double[]> callable = new Callable_class_1a();
for(int i = 0; i < 1; i++) {
//Submit the task for execution.
Future<double[]> future = service.submit(callable);
list.add(future);
}
for(Future<double[]> futu : list) {
try {
System.out.print(Arrays.toString(futu.get()));
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} finally {
service.shutdown();
}
}
}
And the code above is the main function that supposed to print out the value that I get from call() function. I ran this on Eclipse, and when I clicked run nothing happened.
I wonder what happened, and how do I solve this?
I can clarify any part that confused you.
This is my first every question on Stackoverflow, hope everyone treat me nicely :)

Unable to call getter for a Runnable in a ArrayList<thread>?

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.

How to achieve synchronization of three threads using reentrant lock?

Below specified code snippet prints numbers in sequence with synchronizing three threads using wait() and notify() methods. But the requirement is to achieve the same using reentrant locking mechanism.
class JoinTask {
private int currentRank = 1;
public void doJob(int rank, int printNo) {
synchronized (this) {
while (rank != currentRank) {
try {
System.out.println("going to wait by thread:" + printNo);
wait();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
System.out.println("Job:" + printNo + " : " + currentRank);
currentRank++;
notifyAll();
}
}
}
public class ThreeThreadsPlay {
public static void main(String[] args) {
final JoinTask task = new JoinTask();
Thread A = new Thread() {
public void run() {
int k = 1;
for (int i = 1; i < 30; i++) {
task.doJob(k, 1);
k = k + 3;
}}};
Thread B = new Thread() {
public void run() {
int k = 2;
for (int i = 1; i < 30; i++) {
task.doJob(k, 2);
k = k + 3;
}}};
Thread C = new Thread() {
public void run() {
int k = 3;
for (int i = 1; i < 30; i++) {
task.doJob(k, 3);
k = k + 3;
}}};
C.start();
B.start();
A.start();
}}
How can I achieve the same using reentrant locking?
Any other example using reentrant locking to provide such mechanism will also help. Furthermore, any information provided in this context will be highly appreciated.
Here's a proper implementation with ReentrantLock/Conditional. Note carefully the differences between this and what you attempted. The lock acquisition and release should really be handled in a try-finally block to avoid a lock being kept indefinitely, but you can find examples of that in other questions.
class JoinTask {
private int currentRank = 1;
final ReentrantLock l = new ReentrantLock();
final Condition c = l.newCondition();
public void doJob(int rank, int threadNumber) {
l.lock();
while(rank != currentRank) {
c.await();
}
System.out.println("Job:" + threadNumber + " : " + currentRank);
currentRank++;
c.signalAll();
l.unlock();
}
}

Netbeans, red text but no error

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

Categories

Resources