How can I switch between threads created from thread pool? I have many threads created but I only want 1 thread to print something and others to be in wait state. Now after printing, I want this thread to go in wait state and some other thread to acquire this lock and print just like the previous thread and then go into wait state. This simulation keeps on occuring again and again until some condition satisfies. There is randomization of threads acquiring the lock and it doesn't need to be in order. If possible later you can exlain how can I achieve that in order maybe using queue.
I am new to threads, so something that I was trying to achieve is below. I know its wrong but I wanted you to give a solution and little explanation in terms of what I want to achieve.
public class Processor implements Runnable{
private int id;
public Processor(int id) {
this.id = id;
}
#Override
public void run() {
int count=0;
System.out.println("Starting process id: " + id);
while(count<100) {
System.out.println("Pausing process id: "+id);
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
notifyAll();
System.out.println("Resuming process id: "+id);
count++;
}
System.out.println("Completed process id: " + id);
}
}
public class Test {
#SuppressWarnings("resource")
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
System.out.print("Enter number of processes you want to create: ");
int n = reader.nextInt();
ExecutorService executor = Executors.newFixedThreadPool(n);
for(int i=1;i<=n; i++) {
executor.submit(new Processor(i));
}
executor.shutdown();
try {
executor.awaitTermination(10, TimeUnit.MINUTES);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
It is not possible to programmatically control the order in which threads are instantiated. The priority of threads and their execution is determined by the particular Operating System's thread scheduling algorithm implementation.
Related
I've been looking at a solution for the dining philosopher problem on wikipedia.
The resource hierarchy solution
I understand how it works and how breaking the circular structure prevents deadlocks but how does the solution prevent starvation? Couldn't one or a few threads keep going while a few wont get to make progress?
If not, what prevents this from happening?
The implementation:
public class DinningphilMain {
public static void main(String[] args) throws InterruptedException {
int numPhil = 3;
Philosopher[] phil = new Philosopher[numPhil];
Fork[] forkArr=new Fork[numPhil];
for (int i = 0; i < numPhil; i ++) {
forkArr[i]= new Fork(i);
}
for (int i = 0; i < numPhil-1; i++) {
phil[i]=new Philosopher(i, forkArr[i], forkArr[i+1]);
}
phil[numPhil-1]= new Philosopher(numPhil-1, forkArr[0], forkArr[numPhil-1]);
for (Philosopher p : phil)
new Thread(p).start();
}
}
This is the philosopher class
import java.util.Random;
public class Philosopher implements Runnable {
int sleep = 1000;
int id;
int eatTime= 500;
Random rand = new Random();
Fork left;
Fork right;
public Philosopher(int id, Fork left, Fork right) {
this.id = id;
this.left = left;
this.right = right;
}
private void think() {
System.out.println("Philosopher " + id + " is thinking");
try {
int thinkingTime = rand.nextInt(sleep);
Thread.sleep(thinkingTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void getForks() {
System.out.println("Philosopher " + id + " is picking up forks");
try {
left.get();
right.get();
System.out.println("Philosopher " + id + " has both forks");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void releaseForks() {
System.out.println("Philosopher " + id + " is putting down forks");
left.release();
right.release();
}
private void eat() {
System.out.println("Philosopher " + id + " is eating");
try {
Thread.sleep(eatTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
#Override
public void run() {
while (true) {
getForks();
eat();
releaseForks();
think();
}
}
}
This is the fork class
public class Fork {
private int id;
private Thread thread;
public Fork(int id) {
this.id = id;
thread = null;
}
public int getId() {
return id;
}
public synchronized void get() throws InterruptedException {
if (thread != null)
this.wait();
thread = Thread.currentThread();
}
public synchronized void release() {
if (thread == Thread.currentThread())
thread = null;
this.notify();
}
}
The resource hierarchy solution solves deadlocks but doesn't solves starvation.
In order to prevent starvation you either need:
A guarantee from the thread system that threads will be unblocked from
monitors and condition variables in the same order that they are
blocked.
To do it yourself. In other words, you must guarantee that no
philosopher may starve. For example, suppose you maintain a queue of
philosophers. When a philosopher is hungry, he/she gets put onto the
tail of the queue. A philosopher may eat only if he/she is at the head
of the queue, and if the chopsticks are free.
This is taken from C560 Lecture notes -- Dining Philosophers
The short answer is that it doesn't. The dining philosophers problem is used to discuss the problem of concurrency; it in itself is not a single solution for anything (hence why it's called a problem).
The wikipedia page for the dining philosophers itself shows a few implementations. The first one shows how a poor implementation for a solution will cause starvation.
https://en.wikipedia.org/wiki/Dining_philosophers_problem
public class SetGetFail implements Runnable {
// Every thread is assigned a number and has a reference to a SharedObject.
// In main(), a single SharedObject is passed to all threads.
int number;
SharedObject shared;
public SetGetFail(int no, SharedObject so) {
number = no;
shared = so;
}
public static void main(String[] args) {
SharedObject shared = new SharedObject(0);
new Thread(new SetGetFail(1, shared)).start();
new Thread(new SetGetFail(2, shared)).start();
}
synchronized public void run() {
setGet();
}
synchronized void setGet() {
// Repeatedly assign this thread's own number to the shared
// object and race to read that number again.
// Exit, if some other thread modified the number in between.
while(true) {
shared.setNo(number);
int no = shared.getNo();
if (no != number) {
System.out.println("Thread " + number + " sees " + no);
System.exit(no);
}
}
}}
So my question to the code is, why "synchronized" do not prevent races between these threads?
Thread 2 should be locked while Thread 1 is getting/setting the Value from shared, but the result is still "Thread 2 sees 1".
Change the code like this. I have added an additional log statement just to prove you that it is running. Now let me explain the issue. You have just declared the method that modifies the shared state as this.
synchronized void setGet() {
// ...
}
So each thread gets it's own lock and modify the shared data at the same time. That's why your thread-2 sees the value 1 which is set by the other thread. To guard this you need to use a lock which is common to both the thread1 and thread2 instances. For that you need to use an explicit lock object which is shared among both the threads and synchronize using that shared lock. So that's what I have done to solve the issue.
private static final Object lock = new Object();
synchronized (lock) {
// ...
}
public class SetGetFail implements Runnable {
// Every thread is assigned a number and has a reference to a SharedObject.
// In main(), a single SharedObject is passed to all threads.
int number;
SharedObject shared;
private static Object lock = new Object();
public SetGetFail(int no, SharedObject so) {
number = no;
shared = so;
}
public static void main(String[] args) throws InterruptedException {
SharedObject shared = new SharedObject(0);
new Thread(new SetGetFail(1, shared), "One").start();
new Thread(new SetGetFail(2, shared), "Two").start();
}
synchronized public void run() {
setGet();
}
void setGet() {
// Repeatedly assign this thread's own number to the shared
// object and race to read that number again.
// Exit, if some other thread modified the number in between.
while (true) {
synchronized (lock) {
shared.setNo(number);
int no = shared.getNo();
if (no != number) {
System.out.println("Thread " + number + " sees " + no);
System.exit(no);
}
System.out.println("Thread " + number + " sees " + no);
}
}
}
}
I would like to know if the following method is correct or not.
I've producer and consumer thread that work on a common BlockingQueue.
The producer is a sniffer thread so it will stop automatically,but fot the consumer i think to terminate with a loop on status (alive/dead) of producer thread. Any suggestions? Thanks
-)From the Main thread:
ArrayBlockingQueue<PcapPacket> queue = new ArrayBlockingQueue<>();
Producer p = new Producer(queue);
Thread t1 =new Thread(p);
t1.start();
Consumer c = new Consumer(queue,t1);
new Thread(c).start();
-)Producer
public void run() {
public void nextPacket(PcapPacket packet, String user) {
try {
queue.put(packet);
} catch (InterruptedException ex) {
}
-) Consumer
public void run() {
while(producer.isAlive()){
try {
//Thread.sleep(50);
packet=queue.take();
Polling producer's status is sub-optimal.
Preferred approach is to make producer, during producer exit, put some 'poison pill' into queue, and for consumer to end it's loop as soon as it have received that pill:
class Producer implements Runnable {
static final Object TIME_TO_STOP = new Object();
private final BlockingQueue<Object> q;
Producer(BlockingQueue<Object> q) {
this.q = q;
}
#Override
public void run() {
try {
while (true) {
q.put(readNextPacket());
}
} finally {
// exception happened
try {
q.put(TIME_TO_STOP);
} catch (InterruptedException e) {
// somehow log failure to stop properly
}
}
}
}
class Consumer implements Runnable {
private final BlockingQueue<Object> q;
Consumer(BlockingQueue<Object> q) {
this.q = q;
}
#Override
public void run() {
while (true) {
Object packet = q.take();
if (packet == Producer.TIME_TO_STOP) {
break;
}
// process packet
}
}
}
I have a TableView associated with some data, and once i hit a run button i perform some processing on that data. Each row of data is handled in a seperate thread, and while those threads are running i want a ProgressInducator to replace the table within its vbox.
In the attached code:
If I stop where is says "WORKS IF STOP HERE" - table is replaced with pi.
If I continue waiting for the threads to join - no replacing.
What am I missing?
runButton.setOnAction(
new EventHandler<ActionEvent>() {
#Override
public void handle(final ActionEvent e) {
List<Thread> threadList = new ArrayList<Thread>();
int threadCounter = 0;
final ProgressIndicator pi = new ProgressIndicator(threadCounter);
vbox.getChildren().clear();
vbox.getChildren().addAll(pi);
for (ProductInTable product : data) {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try
{
product.calculate();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
});
threadList.add(thread);
thread.start();
}
int x = threadList.size();
/** WORKS IF STOP HERE **/
// wait for all threads to end
for (Thread t : threadList) {
try {
t.join();
threadCounter++;
pi.setProgress(threadCounter / x);
} catch (InterruptedException interE) {
interE.printStackTrace();
}
}
/** DOESNT WORKS IF STOP HERE **/
Thread.join() blocks execution until the thread is completed. Since you are calling this on the FX Application Thread, you block that thread until all your worker threads finish. This means the UI is unable to update until those threads are complete.
A better approach is probably to represent each computation with a task, and update a counter of complete tasks back on the FX Application Thread using setOnSucceeded. Something like:
runButton.setOnAction(
new EventHandler<ActionEvent>() {
#Override
public void handle(final ActionEvent e) {
final ProgressIndicator pi = new ProgressIndicator(threadCounter);
vbox.getChildren().clear();
vbox.getChildren().addAll(pi);
final int numTasks = data.size();
// only access from FX Application thread:
final IntegerProperty completedTaskCount = new SimpleIntegerProperty(0);
pi.progressProperty().bind(completedTaskCount.divide(1.0*numTasks));
completedTaskCount.addListener(new ChangeListener<Number>() {
#Override
public void changed(ObservableValue<? extends Number> obs, Number oldValue, Number newValue) {
if (newValue.intValue() >= numTasks) {
// hide progress indicator and show table..
}
}
});
for (final ProductInTable product : data) {
Task<Void> task = new Task<Void>() {
#Override
public Void call() {
try
{
product.calculate();
} catch (IOException ioe) {
ioe.printStackTrace();
}
return null ;
}
});
task.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
#Override
public void handle(WorkerStateEvent event) {
completedTaskCount.set(completedTaskCount.get()+1);
}
});
new Thread(task).start();
}
}
});
If you potentially have a large number of items here, you should use some kind of ExecutorService instead to avoid creating too many threads:
ExecutorService exec = Executors.newFixedThreadPool(
Runtime.getRuntime().availableProcessors()); // for example...
and then replace
new Thread(task).start();
with
exec.submit(task);
class Program
{
static void Main(string[] args)
{
Thread thread1 = new Thread((ThreadStart)DLockSample.FunctionA);
Thread therad2 = new Thread((ThreadStart)DLockSample.FunctionB);
thread1.Start();
therad2.Start();
}
}
public class DLockSample
{
static object object1 = new object();
static object object2 = new object();
public static void FunctionA()
{
lock (object1)
{
Thread.Sleep(1000);
lock (object2)
{
Thread.Sleep(1000);
Console.WriteLine("heart beat - object2");
}
}
}
public static void FunctionB()
{
lock (object2)
{
lock (object1)
{
Thread.Sleep(1000);
Console.WriteLine("heart beat - object1");
}
}
} }
Always enter the locks in the same order in all threads. See also hierarchy of critical sections I.e. FunctionB needs to be:
public static void FunctionB()
{
lock (object1)
{
lock (object2)
...
That's a pretty abstact problem to fix. Just a few tips:
Always lock on objects in the same order
If it's impossible to lock in the same order, use object's fields to preserve the order (for example, if A.Id > B.Id then always lock on A before B).