Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I am trying to design a thread pool at my end in java. As per my design I am using a java's Linkedlist DS inside a main runner thread class to hold on to all the submitted tasks. This task list is getting updated from the main class wherein the main class is adding a tasks to the task list. Inside my main runner thread I am running a while loop and constantly checking for whether the LinkedList is not empty , and if it contains a task then i am retrieving the task and executing it.
The problem here is that I have added a task from my main method in to the task list and I can see the size of this task list to be 1 from main method but inside the runner thread when i print the size of task list object , it shows it as 0.
Need help figuring out what exactly is happening here.
public class ReusableThread<T> extends Thread{
private volatile Queue<Work<T>> tasks = new LinkedList<Work<T>>();
private Work<T> currentWork;
private class Work<T>{
Result<T> result;
Taskable<T> task;
public Work(Result<T> result, Taskable<T> task) {
this.result = result;
this.task = task;
}
}
#Override
public void run() {
while(true){
//System.out.println("ReusableThread.run()");
System.out.println("Inside thread : " + getTasks().size()); //This print 0
if(!tasks.isEmpty()){
currentWork = getWork();
T value = currentWork.task.run();
//currentWork.result.setValue(currentWork.task.run());
}
//currentWork.result.setComplete(true);
}
}
public Work<T> getWork() {
return tasks.remove();
}
public Queue<Work<T>> getTasks() {
return tasks;
}
public Result<T> submit(Taskable<T> task) {
Result<T> result = new Result<T>();
this.tasks.add(new Work<T>(result, task));
return result;
}
}
The main thread is as below :
public void test() throws InterruptedException {
int count = 0;
ReusableThread<Integer> rt = new ReusableThread();
rt.start();
Thread.sleep(1000);
System.out.println("Thread-"+ count +" starting");
Result<Integer> result = rt.submit(JavaUtils::task);
System.out.println("In main : " + rt.getTasks().size()); //This prints 1
}
I think there is a thread-safety problem. Specifically:
a LinkedList is not thread-safe, and
you are using the LinkedList object in rt.getTasks().size() without any synchronization.
This is sufficient to cause size() to return a stale value under some circumstances.
If you are going to rely on the semantics of volatile you need to do a proper analysis of the happens-before relationships for each write / read sequence that matters to thread safety. It is tricky.
My advice would be:
Don't use volatile. Use synchronized and/or an existing thread-safe data structure instead ... if you need to reinvent the wheel.
Don't reinvent the wheel. You could replace your thread pool with a single call Executors.singleThreadExecutor; see javadoc.
You're missing synchronize 'tasks', so two thread (main and ReusableThread) random access to tasks, so you will not know what happen, I've modified your code:
import java.util.LinkedList;
import java.util.Queue;
class Result<T> {
}
interface Taskable<T> {
T run();
}
class JavaUtils {
public static Integer task() {
return 1;
}
}
public class ReusableThread<T> extends Thread{
private volatile Queue<Work<T>> tasks = new LinkedList<Work<T>>();
private Work<T> currentWork;
private class Work<T>{
Result<T> result;
Taskable<T> task;
public Work(Result<T> result, Taskable<T> task) {
this.result = result;
this.task = task;
}
}
#Override
public void run() {
while(true){
//System.out.println("ReusableThread.run()");
synchronized (tasks) {
if (!tasks.isEmpty()) {
System.out.println("Inside thread : " + tasks.size()); //This print 0
currentWork = tasks.remove();
T value = currentWork.task.run();
//currentWork.result.setValue(currentWork.task.run());
}
}
//currentWork.result.setComplete(true);
}
}
public Work<T> getWork() {
synchronized (tasks) {
return tasks.remove();
}
}
public Queue<Work<T>> getTasks() {
synchronized (tasks) {
return tasks;
}
}
public int getTaskSize() {
synchronized (tasks) {
return tasks.size();
}
}
public Result<T> submit(Taskable<T> task) {
Result<T> result = new Result<T>();
synchronized (tasks) {
this.tasks.add(new Work<T>(result, task));
}
return result;
}
public static void test() throws InterruptedException {
int count = 0;
ReusableThread<Integer> rt = new ReusableThread();
rt.start();
Thread.sleep(10);
System.out.println("Thread-"+ count +" starting");
Result<Integer> result = rt.submit(JavaUtils::task);
System.out.println("In main : " + rt.getTaskSize()); //This prints 1
}
public static void main(String[] args) throws Exception {
test();
}
}
and you should add Thread.sleep() to while(true) loop, If don't you will get 100% cpu soon
Related
So my task is this:
Instantiate two object of the same class
Provide a constructor argument, to designate a thread as even and another as odd .
Start both threads right one after other
Odd thread prints odd numbers from 0 to 1000
Even thread prints even numbers from 0 to 1000
However they should be in sync the prints should be 1 , 2 , 3 , 4 .....
One number on each line
However I can't seem to get the locks to release correctly. I've tried reading some of the similar problems on here but they all use multiple classes. What am I doing wrong?
Edit: My main class is doing this -
NumberPrinter oddPrinter = new NumberPrinter("odd");
NumberPrinter evenPrinter = new NumberPrinter("even");
oddPrinter.start();
evenPrinter.start();
and my output is -
odd: 1
even: 2
...
public class NumberPrinter extends Thread {
private String name;
private int starterInt;
private boolean toggle;
public NumberPrinter(String name) {
super.setName(name);
this.name=name;
if(name.equals("odd")) {
starterInt=1;
toggle = true;
}
else if(name.equals("even")) {
starterInt=2;
toggle = false;
}
}
#Override
public synchronized void run() {
int localInt = starterInt;
boolean localToggle = toggle;
if(name.equals("odd")) {
while(localInt<1000) {
while(localToggle == false)
try {
wait();
}catch(InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println(name+": "+localInt);
localInt +=2;
localToggle = false;
notify();
}
}
else {
while(localInt<1000) {
while(localToggle == true)
try {
wait();
}catch(InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println(name+": "+localInt);
localInt +=2;
localToggle = true;
notify();
}
}
}
}
The key problem here is that the two threads have no way to coordinate with each other. When you have a local variable (localToggle in this case) nothing outside the method can observe or alter its value.
If you share one object with both threads, however, its state can change, and if used correctly, those state changes will be visible to both threads.
You will see examples where the shared object is an AtomicInteger, but when you use synchronized, wait() and notify(), you don't need the extra concurrency overhead built into the atomic wrappers.
Here's a simple outline:
class Main {
public static main(String... args) {
Main state = new Main();
new Thread(new Counter(state, false)).start();
new Thread(new Counter(state, true)).start();
}
int counter;
private static class Counter implements Runnable {
private final Main state;
private final boolean even;
Counter(Main state, boolean even) {
this.state = state;
this.even = even;
}
#Override
public void run() {
synchronized(state) {
/* Here, use wait and notify to read and update state.counter
* appropriately according to the "even" flag.
*/
}
}
}
}
I'm not clear whether using wait() and notify() yourself is part of the assignment, but an alternative to this outline would be to use something like a BlockingQueue to pass a token back and forth between the two threads. The (error-prone) condition monitoring would be built into the queue, cleaning up your code and making mistakes less likely.
I finally got it working in a way that meets the standards required by my assignment.
Thank you all for your input. I'll leave the answer here for anyone who might need it.
public class Demo {
public static void main(String[] args) {
NumberPrinter oddPrinter = new NumberPrinter("odd");
NumberPrinter evenPrinter = new NumberPrinter("even");
oddPrinter.start();
evenPrinter.start();
System.out.println("Calling thread Done");
}
public class NumberPrinter extends Thread {
private int max = 1000;
static Object lock = new Object();
String name;
int remainder;
static int startNumber=1;
public NumberPrinter(String name) {
this.name = name;
if(name.equals("even")) {
remainder=0;
}else {
remainder=1;
}
}
#Override
public void run() {
while(startNumber<max) {
synchronized(lock) {
while(startNumber%2 !=remainder) {
try {
lock.wait();
}catch(InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(name+": "+startNumber);
startNumber++;
lock.notifyAll();
}
}
}
}
In class B how can i know jobs of threads are finished? In after properties some worker are running. In class B, I need to know if worker are done?
public class A implements InitializingBean{
public void method1(){
...
}
#Override
public void afterPropertiesSet() throws Exception {
System.out.print("test after properties set");
// send threads to executorService
ExecutorService executorService = Executors
.newFixedThreadPool(4);
for (int i = 0; i < 4; i++) {
Worker worker = new Worker();
executorService.submit(worker);
}
}
}
public class Worker implements Callable<Void>{
#Override
public void call(){
...
}
}
public class B{
public void methodB(){
A a = new A();
a.method1();
///Here How can i know the job of the workers are finished?
}
}
Use a listener/callback pattern to have the thread report completion to a listener. This simple example should show the process:
public interface ThreadCompleteListener {
void workComplete();
}
public class NotifyingThread extends Thread {
private Set<ThreadCompleteListener> listeners;
// setter method(s) for adding/removing listeners to go here
#Override
public void run() {
// do stuff
notifyListeners();
}
private void notifyListeners() {
for (ThreadCompleteListener listener : listeners) {
listener.workComplete(); // notify the listening class
}
}
}
in your listening class:
NotifyingThread t = new NotifyingThread();
t.addListener(new ThreadCompleteListener() {
void workComplete() {
// do something
}
});
t.start();
You could use a Future implementation for your thread. It provides a Future#isDone()
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html#isDone()
In general, it is usually more useful to be notified via a callback when jobs complete. However, since others have posted answers which follow that model, I'll instead post a solution that simply allows you to poll and ask whether the jobs are finished, in case this is what fits the needs of your application better.
public static interface InitializingBean{
public void afterPropertiesSet() throws Exception;
}
public static class A implements InitializingBean{
private List<Future<Void>> submittedJobs = Collections.synchronizedList(new ArrayList<Future<Void>>());
public void method1(){
//do stuff
}
#Override
public void afterPropertiesSet() throws Exception {
System.out.print("test after properties set");
// send threads to executorService
ExecutorService executorService = Executors
.newFixedThreadPool(4);
synchronized (submittedJobs) {
for (int i = 0; i < 4; i++) {
Worker worker = new Worker();
submittedJobs.add(executorService.submit(worker));
}
}
}
/**
* Allows you to poll whether all jobs are finished or not.
* #return
*/
public boolean areAllJobsFinished(){
synchronized (submittedJobs) {
for(Future<Void> task : submittedJobs){
if(!task.isDone()){
return false;
}
}
return true;
}
}
}
public static class Worker implements Callable<Void>{
#Override
public Void call(){
//do worker job
return null; //to satisfy compiler that we're returning something.
}
}
public static class B{
public void methodB(){
A a = new A();
a.method1();
if(a.areAllJobsFinished()){
System.out.println("Congrats, everything is done!");
} else {
System.out.println("There's still some work being done :-(");
}
}
}
If you'd like to wait in that thread that starts the ExecutorService, you can actually use the awaitTermination method.
At the end of you afterPropertiesSet method, you should add:
executorService.shutdown();
After this you then add:
executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)
This causes the thread to wait for all the executorService's tasks to be done and then continues. So place any code you want to execute after the call to awaitTermination.
I have two synchronized methods and I'm using the mediator design pattern.
I'm trying to avoid deadlocks, which is (from what I understand) for example when a thread has a lock on a variable res1 but needs a lock on variable res2. The other thread needs the lock for res1 but has the lock for res2 - resulting in a deadlock, right?
Assuming my understanding of deadlocks are correct, then my question is whether or not I have solved the issue of deadlock in this code?
I have two synchronized methods and two threads.
public class Producer extends Thread {
private Mediator med;
private int id;
private static int count = 1;
public Producer(Mediator m) {
med = m;
id = count++;
}
public void run() {
int num;
while(true) {
num = (int)(Math.random()*100);
med.storeMessage(num);
System.out.println("P-" + id + ": " + num);
}
}
}
public class Consumer extends Thread {
private Mediator med;
private int id;
private static int count = 1;
// laver kopling over til mediator
public Consumer(Mediator m) {
med = m;
id = count++;
}
public void run() {
int num;
while(true) {
num = med.retrieveMessage();
System.out.println("C" + id + ": " + num);
}
}
}
public class Mediator {
private int number;
private boolean slotFull = false;
public synchronized void storeMessage(int num) {
while(slotFull == true) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
slotFull = true;
number = num;
notifyAll();
}
public synchronized int retrieveMessage() {
while(slotFull == false) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
slotFull = false;
notifyAll();
return number;
}
}
public class MediatorTest {
public static void main(String[] args) {
Mediator mb = new Mediator();
new Producer(mb).start();
new Producer(mb).start();
new Producer(mb).start();
new Consumer(mb).start();
new Consumer(mb).start();
}
}
for example when a thread has a lock on a variable res1 but needs a lock on variable res2
What matters is not that there are two variables, what matters is that there must be two (or more) locks.
The names "res1" and "res2" are meant to suggest two resources each of which may have one or more variables, and each of which has its own lock. Here's where you get into trouble:
final Object lock1 = new Object();
final Object lock2 = new Object();
public void method1() {
synchronized (lock1) {
// Call Thread.sleep(1000) here to simulate the thread losing its time slice.
synchronized(lock2) {
doSomethingThatRequiresBothLocks
}
}
}
public void method2() {
synchronized (lock2) {
// Do the same here 'cause you can't know which thread will get to run first.
synchronized(lock1) {
doSomethingElseThatRequiresBothLocks()
}
}
}
If thread A calls method1(), there is a very small chance that it could lose its time slice (i.e., turn to run) just after it successfully locks lock1, but before it locks lock2.
Then, while thread A is waiting its turn to run again, thread B calls method2(). Thread B will be able to lock lock2, but then it gets stuck because lock1 is locked by thread A. Furthermore, when thread A gets to run again, it will immediately be blocked when it tries to lock lock2 which is owned by thread B. Neither thread will ever be able to continue from that point.
In real code, it's never so obvious. When it happens in real-life, it usually is because of some unforseen interaction between code from two or more different modules that may not even be aware of each other, but which access the same common resources.
Your understanding of the basic deadlock problem is correct. With your second question about validity of your solution to the deadlock problem, you've only got 1 lock, so I'd say "yes" by default, since the deadlock you described isn't possible in this situation
I agree with what #ControlAltDel has said. And your understanding of a deadlock matches mine. Whereas there are a few different ways in which a deadlock can manifest itself, the way you describe -- inconsistently acquiring multiple monitors by involved threads (methods) causes deadlock.
Another way would be to (for example,) sleep while holding a lock. As you coded correctly, when the producer finds that slotFull = true, it waits, giving up the lock, so the other thread (consumer, which is sharing the same instance of Mediator with producer) can make progress potentially causing this thread also to make progress after it gets a notification. If you had chosen to call Thread.sleep() instead (naively hoping that someone will cause the sleep to end when the condition would be false), then it would cause a deadlock because this thread is sleeping, still holding the lock, denying access to the other thread.
Every object has one lock which restrict multiple threads to access same block of code or method when you use synchronized keyword.
Coming to your problem, it will not deadlock.
If you have two independent attribute in a class shared by multiple threads, you must synchronized the access to each variable, but there is no problem if one thread is accessing one of the attribute and another thread accessing the other at the same time.
class Cinema {
private long vacanciesCinema1; private long vacanciesCinema2;
private final Object controlCinema1, controlCinema2;
public Cinema() {
controlCinema1 = new Object();
controlCinema2 = new Object();
vacanciesCinema1 = 20;
vacanciesCinema2 = 20;
}
public boolean sellTickets1(int number) {
synchronized (controlCinema1) {
if (number < vacanciesCinema1) {
vacanciesCinema1 -= number;
return true;
} else {
return false;
}
}
}
public boolean sellTickets2(int number) {
synchronized (controlCinema2) {
if (number < vacanciesCinema2) {
vacanciesCinema2 -= number;
return true;
} else {
return false;
}
}
}
public boolean returnTickets1(int number) {
synchronized (controlCinema1) {
vacanciesCinema1 += number;
return true;
}
}
public boolean returnTickets2(int number) {
synchronized (controlCinema2) {
vacanciesCinema2 += number;
return true;
}
}
public long getVacanciesCinema1() {
return vacanciesCinema1;
}
public long getVacanciesCinema2() {
return vacanciesCinema2;
}
}
class TicketOffice1 implements Runnable {
private final Cinema cinema;
public TicketOffice1(Cinema cinema) {
this.cinema = cinema;
}
#Override
public void run() {
cinema.sellTickets1(3);
cinema.sellTickets1(2);
cinema.sellTickets2(2);
cinema.returnTickets1(3);
cinema.sellTickets1(5);
cinema.sellTickets2(2);
cinema.sellTickets2(2);
cinema.sellTickets2(2);
}
}
public class CinemaMain {
public static void main(String[] args) {
Cinema cinema = new Cinema();
TicketOffice1 ticketOffice1 = new TicketOffice1(cinema);
Thread thread1 = new Thread(ticketOffice1, "TicketOffice1");
TicketOffice2 ticketOffice2 = new TicketOffice2(cinema);
Thread thread2 = new Thread(ticketOffice2, "TicketOffice2");
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("Room 1 Vacancies: %d\n", cinema.getVacanciesCinema1());
System.out.printf("Room 2 Vacancies: %d\n", cinema.getVacanciesCinema2());
}
}
Ok, so, I have a java class in which every method must run in a thread.
only one thread is executed per time and at a specific time.
I've implemented like this, with a inner class that extends Thread.
private class MyOperation extends Thread {
public static final String M1 = "method1";
public static final String M2 = "method2";
public static final String M3 = "method3";
protected long scheduledStartTime = 0;
private String type;
public MyOperation(String type, long milliSecondsToWait) {
this.type = type;
scheduledStartTime = System.currentTimeMillis() + mlliSecondsToWait;
}
#Override
public void run() {
switch(type){
case M1:
doMethod1();
break;
case M2:
doMethod3();
break;
case M3:
doMethod3();
break;
}
setCurrentOperation(null);
}
}
private void setCurrentOperation(MyOperation task) {
synchronized (currentOperation) {
this.currentOperation = task;
}
}
then I have the Thread queue and the current running thread
private MyOperation currentOperation;
private Queue <MyOperation> operationList;
And I'm fetching tasks like this:
private void fetchTasks() {
new Thread() {
#Override
public void run() {
while(true) {
if(currentOperation == null && !operationList.isEmpty()) {
currentOperation = getOperation();
while(currentOperation.scheduledStartTime > System.currentTimeMillis()) {
// do nothing, wait for proper time;
}
currentOperation.start();
}
}
}
}.start();
}
private MyOperation getOperation() {
synchronized (operationList) {
return operationList.remove();
}
}
and I'm adding thread to the queue like this, for example:
addOperation(new MyOperation(M1, 5));
private void addOperation(MyOperation task) {
synchronized (operationList) {
operationList.add(task);
}
}
My questions are:
Is there a better way to run each method in a diffent thread?
Is this way of fetching the threads queue correct?
Thank you very much
Just a little thing: if your operationsList is empty or the currentOperation is not null your thread starts going in circles really fast.
You could use Thread.wait() and .notify() to avoid this.
Also you are using currentOperation with and without synchronized. This could get you into trouble.
Have you condsidered using a ScheduledExecutorService (java.util.concurrent) to schedule your tasks?
Can someone please help me out.
I need to use two threads in a way that one thread will run permanently while(true) and will keep track of a positioning pointer (some random value coming in form a method). This thread has a logic, if the value equals something, it should start the new thread. And if the value does not equal it should stop the other thread.
Can someone give me some code snippet (block level) about how to realize this?
Create a class that implements Runnable. There you'll make a run() method.
Like:
public class StackOverflow implements Runnable{
private Thread t = null;
public void run(){
}
public void setAnotherThread(Thread t){
this.t = t;
}
}
On the main class, you'll create 2 instances of Thread based on the other class you created.
StackOverflow so1 = new StackOverflow();
StackOverflow so2 = new StackOverflow();
Thread t1 = new Thread(so1);
Thread t2 = new Thread(so2)
Then you set one thread in the other, so you can control it.
t1.setAnotherThread(so2);
t2.setAnotherThread(so1);
Then you do what you need to do.
Ok if I'm not mistaken, you want to have one class that could be run as a "Thread" or as a (lets call it) a "sub-Thread".
But how to do that with one run method? just declare a boolean variable that specifies whether the thread object is a sub-thread or a parent thread, and accordingly declare two constructors, one would create a parent thread and the other would create a sub thread, and to be able to stop the sub-thread declare another variable called stop that is default to false.
class ThreadExample extends Thread {
private boolean sub = false;
private ThreadExample subThread = null;
public boolean stop = false;
public ThreadExample() {
}
public ThreadExample(boolean sub) {
this.sub = sub;
}
public void run() {
if (sub) {
runSubMethod();
} else {
runParentMethod();
}
}
public void runParentMethod() {
boolean running = true;
while (running) {
if (getRandomValue() == some_other_value) {
if (getSubThread().isAlive()) {
continue;
}
getSubThread().start();
} else {
getSubThread().makeStop();
}
}
}
public void runSubMethod(){
while(true){
//do stuff
if (stop)
break;
}
}
public int getRandomValue() {
//your "Random Value"
return 0;
}
private ThreadExample getSubThread() {
if (subThread == null) {
subThread = new ThreadExample(true);
}
return subThread;
}
public void makeStop(){
stop = true;
}
}
Here is a simple idea how you can implement as many threads as you like in a class:
class MultipleThreads{
Runnable r1 = new Runnable() {
public void run() {
... code to be executed ...
}
};
//-----
Runnable r2 = new Runnable() {
public void run() {
... code to be executed ...
}
};
//--- continue as much you like
public static void main (String[] args){
Thread thr1 = new Thread(r1);
Thread thr2 = new Thread(r2);
thr1.start();
thr2.start();
}
}
Hope it helps!!
For communicating between the two threads, one simple solution is to set a boolean type volatile static variable, and have it set from one thread and put it in while(flag) condition in the other thread.
You can control the other thread using this method.
And if you have waiting processes or Thread.sleep() and you want to break the thread without having it to finish it, your interrupts by catching the exception.