I have the following code :
import java.util.ArrayList;
public class main {
final static Object lock= new Object();
public static void main(String[] args) {
for (int i = 0; i < 100000; i++) {
System.out.println("-------");
finish finished = new finish(false);
ArrayList<Boolean> arr = new ArrayList<>();
Thread t1 = new Thread(() -> {
System.out.println(Thread.currentThread().getId() + " Is setting");
finished.setFinished(true);
});
t1.start();
synchronized (lock){
if (finished.isFinished == false) {
System.out.println(Thread.currentThread().getId() + " Is adding");
arr.add(new Boolean(finished.isFinished));
} else {
System.out.println("Done");
}
}
System.out.println("The length of array is " + arr.size());
if (arr.size() > 0) {
System.out.println("The val of array is " + arr.get(0));
}
}
}
}
class finish {
public boolean isFinished = false;
public finish(boolean finished) {
this.isFinished = finished;
}
public void setFinished(boolean finished) {
this.isFinished = finished;
}
}
I am expecting to get the following output :
The length of array is 1
The val of array is false
or
Done
It is the case most of the times.
But sometimes the output is :
The length of array is 1
The val of array is true
It means, that there was a context switch in the critical section.
I have tried to synchronized the code on an object, but it did not help.
It is a classical synchronization problem, I but was not able to solve it.
Maybe I should use atomic objects, but I have no idea how would they help in this case.
Or perhaps I am to harsh with java, and I should not test it in a for loop? I am running this example on a Linux OS.
I think my synchronization does not make sense. But I don't know how to solve it.
It's not at all clear what your example code is trying to do, but if you want to wait for the thread to finish, use t1.join() and deal with the InterruptedException that this throws. Also, finished should be an AtomicBoolean if you're going to use it in more than one thread.
But all in all, the code is pretty problematic, and doesn't reflect whatever real-life scenario you're trying to deal with.
In this code you are reading the same variable twice, which allows for the possibility it can be changed. The simplest solution is to read it just once.
boolean isFinished = finished.isFinished;
if (isFinished) {
System.out.println("Done");
} else {
System.out.println(t1 + " Is adding");
arr.add(isFinished);
}
Related
This question already has answers here:
How threads are executed in the memory?
(2 answers)
Closed 2 years ago.
This is a simplified version of the problem. Given n number of threads, each printing a constant number all the time. For example, Thread-1 should always print 1, Thread-2 should always print 2 and so on...
How to ensure, the threads are executed in order i.e. the output should be as below:
Thread-1: 1
Thread-2: 2
Thread-3: 3
.
.
.
Thread-n: n
I have a naïve solution to do it through wait()/notify() but I guess there might be a better solution than that. Perhaps, using Semaphore maybe? I don't know.
Update:
Based on the answers received, I think I was not very clear. There are some constraints:
All threads should start at once (assume we don't really have control on that)
Once all the threads start, there should be some sort of communication between the threads to execute in order.
This sequentially execution of thread can be handled beautifully using Thread.join() method. To handle it properly, you may have to create MyRunnable(or, use any name you prefer) which implements Runnable interface. Inside MyRunnable, you can inject a parent Thread, and call parent.join() at top of MyRunnable.run() method. The code is given below:
public class SequentialThreadsTest {
static class MyRunnable implements Runnable {
static int objCount; // to keep count of sequential object
private int objNum;
private Thread parent; // keep track of parent thread
MyRunnable(Thread parent) {
this.parent = parent;
this.objNum = objCount + 1;
objCount += 1;
}
#Override
public void run() {
try {
if(parent != null) {
parent.join();
}
System.out.println("Thread-" + objNum + ": " + objNum);
} catch(InterruptedException e) {
e.printStackTrace();
// do something else
} finally {
// do what you need to do when thread execution is finished
}
}
}
public static void main(String[] args) {
int n = 10;
Thread parentThread = null;
for(int i=0; i<n; i++) {
Thread thread = new Thread(new MyRunnable(parentThread));
thread.start();
parentThread = thread;
}
}
}
And the output is:
Thread-1: 1
Thread-2: 2
Thread-3: 3
Thread-4: 4
Thread-5: 5
Thread-6: 6
Thread-7: 7
Thread-8: 8
Thread-9: 9
Thread-10: 10
You haven't specified many details, but if you only want serializable thread execution you can wait for previous thread to finish and then print. Something like this:
public static void main(String[] args) {
Thread thread = null;
for (int i = 0; i < 10; i++) {
int index = i;
Thread previousThread = thread;
thread = new Thread(() -> {
if (previousThread != null) {
try {
previousThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(index);
});
thread.start();
}
}
Try making a queue - this will do exactly what you want. Simply change the value of n to however many threads you have, and add all the threads sequentially (only once). If ever you want to stop the threads from executing, all you have to do is add end to the queue. Obviously, for a larger project, you will need to modify this code a little bit (I would recommend replacing the main method with a class initializer and pass the LinkedBlockingQueue as a pre-built argument)
import java.util.concurrent.LinkedBlockingQueue;
public class HelloWorld{
private static int n = 2;
private static LinkedBlockingQueue<Thread> queue = new LinkedBlockingQueue<>(n+1);
static Thread a = new Thread(()->{
System.out.print("a");
});
static Thread b = new Thread(()->{
System.out.print("b");
});
static Thread end = new Thread(()->{
break_ = true;
});
public static final int END = 20;//this and the counter are just here so the code doesn't run forever
public static volatile int i = 0;
public static volatile boolean break_ = false;
public static void main(String []args){
queue.add(a);
queue.add(b);
//queue.add(end);
outerloop:
while(true){
Thread toBeRun = queue.poll();
try{
toBeRun.run();
queue.add(toBeRun);
i++;
if(i>=END || break_){//i>=END does not need to be here, it's just to stop it from running forever in this example
break;
}
}catch(NullPointerException e){
break;
}
}
}
}
Note: This uses java 8 lambdas. If you're using an older version of java, you will need to create the threads using the run method.
I could really need some Help on my project.
Task :
The aim of the test is to create a π (Pi) calculation using various
Computation processes accelerated by multi-threading.
Use the BigDecimal class for better precision.
Use your own exception classes and pack all classes in one
neat package concept.
I tried to implement the Leibniz-method and my main issue was that i dont know how to stop a Thread from my main method while the Threads are running. My Teacher showed us and example of his mian method and you can clearly see that he is starting the method with for example 4 threads. And a few seconds later he is able to stop all of the threads.
Here is his example of the main class:
CalculatePi pi = new Leibniz();
System.out.println("Start: " + pi.getMethodName());
pi.startCalculation(4); //four threads
int prec = 0;
BigDecimal result = BigDecimal.ZERO;
long timeStart = System.currentTimeMillis();
while(prec < MAX_PRECISION) {
someDelay(); //give some time to calculate
BigDecimal newResult = pi.getValue();
int newPrec = precicion(result, newResult);
if(newPrec != prec) {
System.out.println("pi (" + newPrec + "): " + newResult);
prec = newPrec;
}
result = newResult;
}
long timeStop = System.currentTimeMillis();
pi.stopCalculation();
System.out.println( (timeStop - timeStart) + " ms");
System.out.println(pi.getInternalSteps() + " calulation steps");
Here are my first Ideas to Implement the task (dont get confused i mainly focus on the method "startCalculation(int numThreads)" and "stopCalculation()" which are both given by an interface)
// Methode soll Leibniz Verfahren mit mehreren Threads berechnen
#Override
public boolean startCalculation(int numThreads) {
// Threads müssen in Array gespeichert werden um damit zu arbeiten
LeibnizThread[] threadSpeicher = new LeibnizThread[numThreads];
for(int i = 0; i < numThreads; i++) {
// Neuen Thread initialisieren und im Array speichern
threadSpeicher[i] = new LeibnizThread(numThreads, i);
//Thread starten
threadSpeicher[i].start();
}
//Warten bis alle Threads fertig sind und ihr ergebnis berechnet haben
for(LeibnizThread w : threadSpeicher)
try {
w.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
BigDecimal sum = new BigDecimal(0.0);
//Summe aller Threads zusammenrechnen
for(LeibnizThread w : threadSpeicher) {
System.out.println(w.getResult() + " Zwischenergebnis");
sum = sum.add(w.getResult());
}
//Summe wird mit 4 multipliziert, um finales Ergebnis zu erhalten
this.value = sum.multiply(new BigDecimal(4));
System.out.println("Ergebnis: " + this.value);
return true;
}
//Methode soll Threads aus Methode startCalculation(numThreads) stoppen, aber wie ?
#Override
public void stopCalculation() {
flag = true;
}
And my Thread class looks like that:
public class LeibnizThread extends Thread {
private int threadRemainder;
private int numThreads;
private BigDecimal result = new BigDecimal(0.0);
private volatile boolean flag = false;
public LeibnizThread(int threadCount, int threadRemainder) {
this.numThreads = threadCount;
this.threadRemainder = threadRemainder;
}
public void run() {
BigDecimal counter = new BigDecimal("1");
while( !flag ) {
if(counter.intValue() % numThreads == threadRemainder)
if(counter.remainder(new BigDecimal("2")).equals(BigDecimal.ONE)) {
result = result.add(BigDecimal.ONE.divide(((new BigDecimal("2").multiply(counter).subtract(BigDecimal.ONE))), 100, RoundingMode.HALF_UP));
}else {
result = result.subtract(BigDecimal.ONE.divide(((new BigDecimal("2").multiply(counter).subtract(BigDecimal.ONE))), 100, RoundingMode.HALF_UP));
}
counter = counter.add(new BigDecimal("1"));
}
}
public BigDecimal getResult() {
return this.result;
}
public void setFlagTrue() {
flag = true;
}
}
I tried to implement a "flag" to make it stop but i dont know how to get impact on the threads which are initialized in the method "startCalculation(numThreads)" from the method "stopCalculation()" .
If anyone has an idea please let me know. Have a nice day and stay healthy :)
To preface; I haven't built and run your code and I haven't really looked up the Leibniz formula, so I'll just keep this answer to your threading question.
It looks like you are facing two problems here:
Calling w.join() will cause your execution to wait until the thread finishes. Unfortunately, the thread will never finish because you will never exit startCalculation(). This is called a deadlock and it's caused when one thread is forever waiting for another to finish.
Even if your execution got to that point, you don't know how to tell the threads to stop.
For the first issue, my advice would be to use one of Java's other helpful thread classes. In this case, you should change LeibnizThread to implement Runnable instead of extending Thread. This will still cause a new thread to be created, but you mostly don't need to worry about the specifics.
For the second issue, you can just move the array of threads out of the method so it gets scoped at the class level. Then, in stopCalculation() you can loop through the threads and tell them to stop.
I wrote up a basic framework for how you can use Runnables in cases like this. Note that this is only one way to do it and there are tons of helpful classes in Java's concurrency library. So look around and see all the tools that are available!
package com.sandbox;
import java.math.BigDecimal;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Leibniz implements CalculatePi {
private Worker[] workers;
#Override
public boolean startCalculation(int numThreads) {
// The executor service handles your thread execution for you
ExecutorService executorService = Executors.newFixedThreadPool(numThreads);
// Start you threads and save a reference to them so you can call them later
workers = new Worker[numThreads];
for (int i = 0; i < numThreads; i++) {
Worker worker = new Worker();
workers[i] = worker;
executorService.submit(worker); // This starts the thread. It calls worker.run().
}
return true;
}
#Override
public void stopCalculation() {
for (Worker worker : workers) {
worker.stopExecution();
}
}
#Override
public BigDecimal getValue() {
BigDecimal result = BigDecimal.ZERO;
for (Worker worker : workers) {
// Do whatever thread consolidation work you need to do here to get a single result
result = result.max(worker.getCurrentResult());
}
return result;
}
private class Worker implements Runnable {
private volatile boolean stopExecution = false; // "volatile" helps make sure the thread actually stops when you want it to by avoiding CPU caches
private BigDecimal currentResult;
Worker() {
// Pass in whatever you need to do the work
}
#Override
public void run() {
while (!stopExecution) {
// Do all of your multi-threaded computation here, setting the currentResult as you go
currentResult = new BigDecimal(System.currentTimeMillis()); // Example.
}
}
void stopExecution() {
this.stopExecution = true;
}
BigDecimal getCurrentResult() {
return currentResult;
}
}
}
And here's a little code that exercises it. It looks a bit like your professor's code.
public static void main(String[] args) throws InterruptedException {
CalculatePi pi = new Leibniz();
pi.startCalculation(4);
for (int i = 0; i < 5; i++) {
sleep(1000);
System.out.println("Current Result: " + pi.getValue());
}
pi.stopCalculation();
BigDecimal finalResult = pi.getValue();
sleep(1000);
BigDecimal verifyFinalResult = pi.getValue();
System.out.println("Workers actually stopped: " + finalResult.equals(verifyFinalResult));
}
Results:
Current Result: 1586477696333
Current Result: 1586477697785
Current Result: 1586477698815
Current Result: 1586477699783
Current Result: 1586477700859
Workers actually stopped: true
I left a lot out because I don't want to do your homework for you, but this should help you get started. Enjoy! :)
I am pretty new to Multithreading programming. In my code threads are trying to acquire locks around few lines. The lines work pretty fine for few context switches but then it halts (probably a deadlock).
On the other hand if use synchronized block then all works fine.
I've four classes.
1. PetersonAlgorithm.java
package com.ashish.master;
public class PetersonAlgorithm {
boolean wantCS[] = {false, false};
int turn = 1;
public void requestCS(int i) {
System.out.println("Lock requested by the thread - " + i);
wantCS[i] = true;
turn = 1 - i;
while(wantCS[1-i] && turn == 1-i);
}
public void releaseCS (int i) {
wantCS[i] = false;
turn = i - 1;
System.out.println("Lock released by the thread - " + i);
}
}
If anyone feels that above algorithm is incorrect then let me know, and feel free to make suggestions.
2. Runner.java
package com.ashish.master;
public class Runner {
public static Incrementer runnableInstance = new Incrementer();
public static Thread inc1 = new Thread(runnableInstance, "0");
public static Thread inc2 = new Thread(runnableInstance, "1");
public static void main(String args[]) {
inc1.start();
inc2.start();
try{
inc1.join();
inc2.join();
} catch (InterruptedException ex) {
System.out.println("The threads have been interrupted while waiting for the join ---> " + ex.getMessage());
}
System.out.println("The total turns taken by incrementer are ----> " + runnableInstance.turns);
}
}
3. Incrementer.java - If synchronized block is used instead of the Peterson algorithm, everything works fine.
package com.ashish.master;
public class Incrementer implements Runnable {
public long turns = 0;
public PetersonAlgorithm pa = new PetersonAlgorithm();
#Override
public void run() {
System.out.println("Thread " + this.toString() + "started.....");
while(true) {
pa.requestCS(Integer.parseInt(this.toString()));
// synchronized(this) {
if(DataStore.data < 1000000) printCriticalSection();
else break;
// }
pa.releaseCS(Integer.parseInt(this.toString()));
}
}
public void printCriticalSection() {
System.out.println("The value of the number is increased by thread " +
this.toString() +" to --> " + DataStore.increase());
turns ++;
}
#Override
public String toString() {
return Thread.currentThread().getName();
}
}
4. DataStore.java A class to mock the data source -- simply increase the number
package com.ashish.master;
public class DataStore {
public static long data = 0L;
public static long increase() {
DataStore.data += 1;
return DataStore.data;
}
}
Your runnables never observe each other's monitors (wantCS and turn) as they have different instances... Each runnable needs to work with a same shared set of monitors!
Take the blue pill and make your PetersonAlgorithm variables static volatile with synchronized block access...
Or take the red pill and you create a Class for your flag monitors (wantCS) and for your indicator monitor (turn). Then just define your runnable with one "own flag", one "observed flag" and one "indicator". Both Runnables will have the same indicator instance (therefore needs to be synchronized) while the flag instances will be crossed (the own flag of R1 will be the observed flag of R2 and the own flag of R2 the observed flag of R1). You should synchronized the flag methods too as you don't want to have a flag raised or lowered while being observed.
Then few steps:
Runnables raise their Flag
Runnables turn the shared Indicator ( set to opponent runnable's id )
Wait if opponent's flag is raised and Indicator is set to opponent.
The non waiting opponent does its stuff then lowers its flag.
The waiting opponent stops waiting (opponent's flag has been lowered), does its stuff and lowers its flag.
Each of your runnable instances has its own PetersonAlgorithm instance. Thus, the two runnables don't know anything about each other and will both always get immediate access to the critical section. Try implementing your PetersonAlgorithm class as static class with static methods. Then change the lines
pa.requestCS(Integer.parseInt(this.toString()));
// ...
pa.releaseCS(Integer.parseInt(this.toString()));
into
PetersonAlgorithm.requestCS(Integer.parseInt(this.toString()));
// ...
PetersonAlgorithm.releaseCS(Integer.parseInt(this.toString()));
I have the following code:
for (int iThreadCounter = 1; iThreadCounter <= CONNECTIONS_NUM; iThreadCounter++){
WorkThread wt = new WorkThread(iThreadCounter);
new Thread(wt).start();
m_arrWorkThreadsToCreate.add(wt);
}
Those threads calls the following code:
int res = m_spLegJoin.call(m_workTread, m_workTread.getConfId());
And this is the call method inside LegJoinSp class:
public class LegJoinSp extends ConnEventSp {
private static final int _LEG_JOIN_ACTION_CODE = 22;
private static int m_nLegId = Integer.valueOf(IniUtils.getIniValue("General", "LEG_ID_START"));
private final Lock m_lock = new ReentrantLock();
public int call(WorkThread a_workThread, String a_sConfId) {
synchronized (this) {
//m_lock.lock();
m_nLegId++;
boolean bPass = false;
Log4jWrapper.writeLog(LogLevelEnum.DEBUG, "LegJoinSp - call", "a_workThread = " + a_workThread.getThreadId() + " a_sConfId = " + a_sConfId);
if (super.call(a_workThread, a_sConfId, _LEG_JOIN_ACTION_CODE, "" + m_nLegId) == 0) {
bPass = true;
} else {
bPass = false;
}
//m_lock.unlock();
if (bPass) {
Log4jWrapper.writeLog(LogLevelEnum.DEBUG, "LegJoinSp - call", "a_workThread = " + a_workThread.getThreadId() + " a_sConfId = " + a_sConfId + " returned leg id " + m_nLegId);
return m_nLegId;
} else {
return -1;
}
}
}
public Lock getLock() {
return m_lock;
}
}
I've got 2 threads calling this call() method.
m_nLegId is initiated with 100.
As you can see I have tried to lock the method with both
synchronized(this)
and
m_lock.lock() and m_lock.unlock()
The problem is that when I first get to if (bPass) inner code, it write 102 to my log as the m_nLegId value. However I expect it to be 101 because of the m_nLegId++; statement.
It seems that the second thread manage to get inside the code before the synchronize block ends for the first thread execution.
How can I fix that?
Thank you
For me your bug is related to the fact that m_nLegId is a static field and you try to synchronize access on the current instance instead of the class such that you don't properly prevent concurrent modifications of your field.
I mean
synchronized (this) {
Should rather be
synchronized (LegJoinSp.class) {
NB: In case you only need a counter, consider using an AtomicInteger for your field instead of an int.
The thing is you are creating a new object with every thread, but the way you applied the lock is applicable only to same object (as you applied the lock on the this).
So if you want to apply the lock on the class level, then you can create a static object and apply the lock on that object which can serve the purpose you wanted to achieve (if I understood your problem correctly based on the comments)
I'm new to using threads and just trying to figure things out. My end game is to have a list of URLs, my program will take one URL from the list at a time and perform an action using that URL. There'll be a lot of URLs and this list may possibly be added to while some threads are using the same list.
To start experimenting and learning I'm using a simple ArrayList filled with numbers and am using a threaded pool to get the URLs. Here's my code:
public static void main(String[] args) {
for (int i = 0; i < 200; i++){
test.add(i);
}
SlothTest runner = new SlothTest();
Thread alpha = new Thread(runner);
Thread beta = new Thread(runner);
ExecutorService tasker = Executors.newFixedThreadPool(10);
while (!listEmpty()){
tasker.submit(new SlothTest());
}
tasker.shutdown();
System.out.println("Complete...");
}
#Override
public void run() {
getLink();
try {
Thread.sleep(20);
} catch (InterruptedException e) {
}
}
private synchronized String getLink(){
link = Thread.currentThread().getName() + " printed " + test.indexOf(test.size()-1);
test.remove(test.size()-1);
System.out.println(link);
return link;
}
private synchronized static boolean listEmpty(){
if (test.size() > 0){
return false;
} else {
return true;
}
}
I'm running into some concurrency issues while running the program and getting some -1's for my output. I'm not sure why this is happening and I know my above code is rough but I'm really in the learning stage a multi-threaded apps. Can anyone help me first off with fixing my concurrency issue and then if you can give me any pointers about my above code that would also be great
One problem is that
while (!listEmpty()){
tasker.submit(new SlothTest());
}
is not atomic. So listEmpty might return false, but become true by the time you reach the next statement.
Another one is that you synchronize on two different monitors:
private synchronized String getLink(){ //synchronized on this
private synchronized static boolean listEmpty(){//synchronized on this.class
Have you considered using a BlockingQueue instead of a list, which has useful methods for what you are trying to achieve.
Try using a ConcurrentLinkedQueue for your list of URLs. This is a good implementation often used in producer-consumer examples, similar to yours (although you don't have an active 'producer', per-se).
You're not globally synchronizing. By using synchronized methods you are locking the current instance, which is different for each task. You should use a global lock instead:
final static Object globalLock = new Object();
private String getLink() {
synchronized (globalLock) {
link = Thread.currentThread().getName() + " printed " + test.indexOf(test.size()-1);
test.remove(test.size()-1);
}
System.out.println(link);
return link;
}
private boolean listEmpty(){
synchronized (globalLock) {
if (test.size() > 0){
return false;
} else {
return true;
}
}
}