How can we simulate starvation in executor framework? - java

I want to simulate a hung thread which we faced in production environment. The application is a web service and different threads are created for new requests. The bug was that all threads were dependent on a synchronized method and that dependency has been removed in patch..
Any pointers how can we simulate the hung threads of executor framework in dev environment?
In Dev, everything is fine, how can I ensure some thread hung for that sync method just like production?
package com.priority;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class StackOverFlow {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < 100; i++) {
executorService.submit(new Task());
}
executorService.shutdown();
}
}
class Task implements Runnable {
synchronized void syncMethod() {
System.out.println("This is the sync method causing issues");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
#Override
public void run() {
syncMethod();
}
}

Let's assume that the synchronized resource (synchronized void syncMethod()) is in some other class so that it is accessible to threads outside of the executorservice. This refactoring is is needed to re-create the starvation scenario.
Create few greedy threads who would hold on to the synchronized resource for random periods (more than normal threads). The number of such threads could be dependent on your test scenario.
Trigger greedy threads before your executor service so that they acquire the resource .
Now you could test how your real threads responds in case of resource scarcity and also define a strategy to manage resource in case of uneven usage.

Without explicit object, synchronized will be performed on this, so the code you posted does not synchronize.
You should give these tasks the same monitor lock:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class StackOverFlow {
public static void main(String[] args) {
Object monitor = new Object();
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < 100; i++) {
executorService.submit(new Task(monitor));
}
executorService.shutdown();
}
}
class Task implements Runnable {
Object monitor;
public Task(Object monitor) {
this.monitor = monitor;
}
void syncMethod() {
synchronized (monitor) {
System.out.println("This is the sync method causing issues");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void run() {
syncMethod();
}
}

Related

Which threading mechanism to use for tasks that enqueue other tasks?

I'm using a task that creates other tasks. Those tasks in turn may or may not create subsequent tasks. I don't know beforehand how many tasks will be created in total. At some point, no more tasks will be created, and all the task will finish.
When the last task is done, I must do some extra stuff.
Which threading mechanism should be used? I've read about CountDownLatch, Cyclic Barrier and Phaser but none seem to fit.
I've also tried using ExecutorService, but I've encountered some issues such as the inability to execute something at the end, and you can see my attempt below:
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
public class Issue {
public static void main(String[] args) throws InterruptedException {
var count = new AtomicInteger(1);
var executor = Executors.newFixedThreadPool(3);
class Task implements Runnable {
final int id = count.getAndIncrement();
#Override
public void run() {
try {
MILLISECONDS.sleep((long)(Math.random() * 1000L + 1000L));
} catch (InterruptedException e) {
// Do nothing
}
if (id < 5) {
executor.submit(new Task());
executor.submit(new Task());
}
System.out.println(id);
}
}
executor.execute(new Task());
executor.shutdown();
// executor.awaitTermination(20, TimeUnit.SECONDS);
System.out.println("Hello");
}
}
This outputs an exception because tasks are added after shutdown() is called, but the expected output would be akin to:
1
2
3
4
5
6
7
8
9
Hello
Which threading mechanism can help me do that?
It seems pretty tricky. If there is even a single task that's either in the queue or currently executing, then since you can't say whether or not it will spawn another task, you have no way to know how long it may run for. It may be the start of a chain of tasks that takes another 2 hours.
I think all the information you'd need to achieve this is encapsulated by the executor implementations. You need to know what's running and what's in the queue.
I think you're unfortunately looking at having to write your own executor. It needn't be complicated and it doesn't have to conform to the JDK's interfaces if you don't want it to. Just something that maintains a thread pool and a queue of tasks. Add the ability to attach listeners to the executor. When the queue is empty and there are no actively executing tasks then you can notify the listeners.
Here's a quick code sketch.
class MyExecutor
{
private final AtomicLong taskId = new AtomicLong();
private final Map<Long, Runnable> idToQueuedTask = new ConcurrentHashMap<>();
private final AtomicLong runningTasks = new AtomicLong();
private final ExecutorService delegate = Executors.newFixedThreadPool(3);
public void submit(Runnable task) {
long id = taskId.incrementAndGet();
final Runnable wrapped = () -> {
taskStarted(id);
try {
task.run();
}
finally {
taskEnded();
}
};
idToQueuedTask.put(id, wrapped);
delegate.submit(wrapped);
}
private void taskStarted(long id) {
idToQueuedTask.remove(id);
runningTasks.incrementAndGet();
}
private void taskEnded() {
final long numRunning = runningTasks.decrementAndGet();
if (numRunning == 0 && idToQueuedTask.isEmpty()) {
System.out.println("Done, time to notify listeners");
}
}
public static void main(String[] args) {
MyExecutor executor = new MyExecutor();
executor.submit(() -> {
System.out.println("Parent task");
try {
Thread.sleep(1000);
}
catch (Exception e) {}
executor.submit(() -> {
System.out.println("Child task");
});
});
}
}
If you change your ExecutorService to this:
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(3);
You could then use the count functions to wait:
while(executor.getTaskCount() > executor.getCompletedTaskCount())
{
TimeUnit.SECONDS.sleep(10L);
}
executor.shutdown();
System.out.println("Hello");

What exactly gets locked when using APIs in java.util.concurrent.Locks?

This is probably a very silly question. I am reading through the documentation of interfaces and classes in packages java.util.concurrent.atomic and java.util.concurrent.locks. I find everywhere that
void lock() – acquire the lock if it’s available; if the lock isn’t available a thread gets blocked until the lock is released
What I am not sure about is, what resource is exactly getting locked? The code snippet examples show
Lock lock = new ReentrantLock();
lock.lock();
try {
// access to the shared resource
} finally {
lock.unlock();
}
Does whatever that is used under the call of lock() get locked? How does JVM know that before getting to that line? And what if there are multiple resources between lock() and unlock()? I guess I am having this question because I am reading this right after reading synchronization and it has very specific way of saying what to lock - like: synchronized(resourceReferenceThatNeedsToBeLocked)
I reseached a lot and yet can't find answer for this question.
You can think of your code like an optimised version of synchronized. You are "synchronizing" on your lock object, but in a more efficient way.
Note that when you're using synchronized, there are no guarantees regarding the resources used inside of the synchronized block. You are just locking on a specific object, which may or may not be the same resources you are using inside of the synchronized block. In essence, regardless of lock or synchronized, you're just saying "make sure no other thread can access the code (or other code guarded by the same lock or ´synchronized´ on the same instance) inside of this block until I'm finished".
The key thing to understand, regardless of lock or synchronized, is that you're guarding a block of code from concurrent access. The code inside the block may access one or several different resources; if the same resources are used elsewhere, access to them needs to be guarded with the same lock or be synchronized on the same instance in order to be safe.
Lock is always associated with data. If there's no data, synchronization is pointless. You have object Thread, Lock, Condition and so on. And then you have data structure that is synchronized with the help of this objects. You need full example. In sample bellow, I'm synchronizing a queue, so that data added to it is always synchronized. Of course it's added to queue from different threads
import java.util.Deque;
import java.util.LinkedList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class BackgroundWorker {
private Worker worker;
private StringBuilder allData;
#Before
public void setUp() throws Exception {
worker = new Worker(allData); // start databse worker
worker.start();
}
#After
public void tearDown() throws Exception {
worker.stop();
}
public void logValue(final String data) {
final LogValue logValue = new LogValue(data);
worker.queue(logValue);
}
#Test
public void test() {
// very dummy, NOT multithreaded test
for (int i = 0; i < 10; i++) {
logValue("Some data " + i);
}
}
private static class Worker implements Runnable {
private static final int MAX_QUEUE_SIZE = 1000;
private final Deque<Job> queue = new LinkedList<Job>();
private final Lock lock = new ReentrantLock();
private final Condition jobAdded = lock.newCondition();
private final Condition jobRemoved = lock.newCondition();
private final StringBuilder dataSource;
private final AtomicBoolean running = new AtomicBoolean(false);
private Thread thread = null;
Worker(final StringBuilder dataSource) {
this.dataSource = dataSource;
}
#Override
public void run() {
processing: for (;;) {
Job job;
lock.lock();
try {
while (null == (job = queue.pollFirst())) {
if (!running.get()) break processing;
try {
jobAdded.await();
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
jobRemoved.signal();
}
finally {
lock.unlock();
}
job.run(dataSource);
}
}
void start() {
lock.lock();
try {
if (running.getAndSet(true)) return; // already running
thread = new Thread(this, "Database worker");
thread.start();
}
finally {
lock.unlock();
}
}
void stop() {
Thread runningThread;
lock.lock();
try {
if (!running.getAndSet(false)) return; // already stopped
runningThread = thread;
thread = null;
jobAdded.signal();
}
finally {
lock.unlock();
}
// wait for the thread to finish while not holding a lock
try {
runningThread.join(2000); // we give it 2 seconds to empty its queue
} catch (InterruptedException e) {
e.printStackTrace();
}
runningThread.interrupt(); // we interrupt it just in case it hasn't finished yet
}
void queue(final Job job) {
if (!running.get()) throw new IllegalStateException("Worker thread is not running");
lock.lock();
try {
while (queue.size() >= MAX_QUEUE_SIZE) {
try {
jobRemoved.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
queue.addLast(job);
jobAdded.signal();
}
finally {
lock.unlock();
}
}
}
private static interface Job {
void run(StringBuilder dataSource);
}
private static class LogValue implements Job {
final String myData;
LogValue(final String data) {
this.myData = data;
}
#Override
public void run(final StringBuilder dataSource) {
dataSource.append(this.myData);
}
}
}
To answer my question:
The object that is locked is the object that reference variable lock is referring to. In this case a ReentrantLock object.
An important thing to note:
The code above is potentially misguiding. Creating a new lock object in a method would be done by respective threads, and the respective thread will only lock that was created in it's stack. If you want to lock a particular instance's variables or methods, that instance should have its own lock object and only that same lock object should be used for synchronisation.
Refer this question for more info. Refer this documentation of the lock in question.

Latch for different task types

I am looking for a java concurrency solution to the following problem.
There are some tasks being run, and a section of code C.
C must wait for all tasks to complete. (With a timeout)
No tasks may commence until C has finished.
I have looked through the java.concurrency package and I found a few things of interest, but nothing seems to work quite right:
Phasers would allow one way blocking, but not two way.
Semaphores, ForkJoinTasks and others have counter-type features but none seem to do what I want.
I believe I could construct something using a phaser and a lock like so:
void C() {
synchronized(lock) {
phaser.awaitAdvanceInterruptibly(phase, 1, TimeUnit.SECONDS);
// Start work anyway if a task is taking too long.
doWork();
}
}
void someTask() {
synchronized(lock) {
phaser.register();
}
doTask().thenRun(
() -> phaser.arriveAndDeregister()
);
}
Now while I'm fairly sure this would work, I'm also aware its a bad idea to try to build your own concurrency solution. Is there a better way of doing this?
If there isn't, what would I use for the phase argument?
Edit: This problem is within a project involving a web client connection, and therefore the tasks arrive unpredictably. However, it is possible that this situation could be avoided by more careful design.
This being a specialized use case, I think we'll need to use multiple concurrency utilities for co-ordination. The below program should do it. Please feel free to post questions of any parts aren't clear -
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
public class TestClass {
private volatile int numOfActiveTasks = 0;
private Semaphore cSemaphore = new Semaphore(1);
private Semaphore taskSemaphore = new Semaphore(1);
private Object tasksLock = new Object();
//Test method
public static void main(String[] args) throws IOException {
TestClass testClass = new TestClass();
//Launch some task threads
ExecutorService taskES = Executors.newFixedThreadPool(2);
IntStream.range(1, 11).forEach((i) -> taskES.submit(() -> {
try {
testClass.executeTask();
} catch (InterruptedException e) {
e.printStackTrace();
}
}));
//Launch some C threads
ExecutorService cES = Executors.newFixedThreadPool(2);
IntStream.range(1, 5).forEach((i) -> cES.submit(() -> {
try {
testClass.C();
} catch (InterruptedException e) {
e.printStackTrace();
}
}));
taskES.shutdown();
cES.shutdown();
}
void C() throws InterruptedException {
try {
cSemaphore.acquire();
//If tasks are running, wait at-least n seconds
this.taskSemaphore.tryAcquire(1, TimeUnit.SECONDS);
print("C started running");
doCsWork();
} finally {
cSemaphore.release();
print("C stopped running");
}
}
void executeTask() throws InterruptedException {
//Do not start while C is running
cSemaphore.acquire();
cSemaphore.release();
synchronized (tasksLock) {
++numOfActiveTasks;
taskSemaphore.tryAcquire();
print("A task started running. Total " + numOfActiveTasks + " tasks running");
}
doTasksWork();
synchronized (tasksLock) {
--numOfActiveTasks;
if (numOfActiveTasks == 0) {
taskSemaphore.release();
}
print("A task stopped running. Total " + numOfActiveTasks + " tasks remaining");
}
}
void doCsWork() throws InterruptedException {
Thread.sleep(1000);
}
void doTasksWork() throws InterruptedException {
Thread.sleep(2000);
}
void print(String message) {
System.out.println(message);
}
}
I found a solution for this problem in java.util.concurrent.locks, which is perfect for my use case.
StampedLock lock;
void C() {
long stamp = lock.tryWriteLock(1, TimeUnit.SECONDS);
doWork();
lock.unlockWrite(stamp);
}
void someTask() {
long stamp = lock.readLock();
doTask().thenRun(() -> lock.unlockRead(stamp));
}
The key with the StampedLock class is that the readLock() is not exclusive, whereas the writeLock() is exclusive. It also supports timeouts, similar to the regular Lock.

Creating a Thread that does not exit

I was wondering what the best way to create a Java Thread that does not terminate.
Currently, I basically have a "Runner" that basically looks like:
ExecutorService pool = Executors.newFixedThreadPool(3);
for (int i = 0; i < numThreads; ++i) {
pool.submit(new Task());
}
pool.shutdown();
and Task looks something like this
public class Task {
...
public void run() {
while(true) { }
}
}
There are two concerns I have with my approach:
Should I be creating a task that just returns after doing work and continue spawning threads that do minimal amounts of work? I'm concerned about the overhead, but am not sure how to measure it.
If I have a Thread that just loops infinitely, when I force quit the executable, will those Threads be shutdown and cleaned up? After some testing, it doesn't appear an InterruptException is being thrown when the code containing the ExecutorService is forcefully shutdown.
EDIT:
To elaborate, the Task looks like
public void run() {
while(true) {
// Let queue be a synchronized, global queue
if (queue has an element) {
// Pop from queue and do a very minimal amount of work on it
// Involves a small amount of network IO (maybe 10-100 ms)
} else {
sleep(2000);
}
}
}
I agree with #D Levant, Blocking queue is the key to use here. With blocking queue, you don't need to handle the queue-empty or queue-full scenario.
In your Task class,
while(true) {
// Let queue be a synchronized, global queue
if (queue has an element) {
// Pop from queue and do a very minimal amount of work on it
// Involves a small amount of network IO (maybe 10-100 ms)
} else {
sleep(2000);
}
}
Its really not a good approach, its inefficient because your while loop is continuously polling, even you have put the thread sleep(), but still its also a overhead of unnecessary context-switches every time the thread wake-ups and sleeps.
In my opinion, your approach of using Executors is looking good for your case. Thread creation is obviously a costly process, and Executors provide us the flexibility of re-using the same thread for different tasks.
You can just pass your task through execute(Runnable) or submit(Runnable/Callable) and then rest will be taken care by Executors internally. Executors internally uses blocking queue concept only.
You can even create your own thread pool by using the ThreadPoolExecutor class and passing the required parameter in its constructor, here you can pass your own blocking queue to hold the tasks. Rest thread-management will be taken care by it on basis of the configuration passes in constructor, So If you are really confident about the configuration parameters then you can go for it.
Now the last point, If you don't want to use the Java's in-built Executors framework, then you can design your solution by using BlockingQueue to hold tasks and starting a thread which will take the tasks from this blocking queue to execute, Below is the high-level implementation:
class TaskRunner {
private int noOfThreads; //The no of threads which you want to run always
private boolean started;
private int taskQueueSize; //No. of tasks that can be in queue at a time, when try to add more tasks, then you have to wait.
private BlockingQueue<Runnable> taskQueue;
private List<Worker> workerThreads;
public TaskRunner(int noOfThreads, int taskQueueSize) {
this.noOfThreads = noOfThreads;
this.taskQueueSize = taskQueueSize;
}
//You can pass any type of task(provided they are implementing Runnable)
public void submitTask(Runnable task) {
if(!started) {
init();
}
try {
taskQueue.put(task);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void shutdown() {
for(Worker worker : workerThreads){
worker.stopped = true;
}
}
private void init() {
this.taskQueue = new LinkedBlockingDeque<>(taskQueueSize);
this.workerThreads = new ArrayList<>(noOfThreads);
for(int i=0; i< noOfThreads; i++) {
Worker worker = new Worker();
workerThreads.add(worker);
worker.start();
}
}
private class Worker extends Thread {
private volatile boolean stopped;
public void run() {
if(!stopped) {
try {
taskQueue.take().run();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
class Task1 implements Runnable {
#Override
public void run() {
//Your implementation for the task of type 1
}
}
class Task2 implements Runnable {
#Override
public void run() {
//Your implementation for the task of type 2
}
}
class Main {
public static void main(String[] args) {
TaskRunner runner = new TaskRunner(3,5);
runner.submitTask(new Task1());
runner.submitTask(new Task2());
runner.shutdown();
}
}

Java - Ideal use of wait and notify?

This code seems to work fine so far in testing. However I am new at multithreading and want to know if this code is ideal, since I know there is a lot of "donts" regarding concurrency.
Is there a better way to make an executor for queued Runnables on a single thread? This is my first time making one so I feel inclined to believe something could be better.
public class ExplosionExecutor{
private static List<Runnable> queue= new ArrayList<Runnable>();
private static Thread thread= new Thread(new Runnable() {
public void run() {
while(true){
Runnable[] queuedump;
synchronized (queue) {
if(queue.size()==0){
try {
queue.wait();
} catch (InterruptedException e){e.printStackTrace();}
}
queuedump= queue.toArray(new Runnable[0]);
queue.clear();
}
for(Runnable r : queuedump)
r.run();
}
}
}, "Nuke Explosions");
static{
thread.start();
}
public static void execute(Runnable command) {
synchronized (queue) {
queue.add(command);
queue.notify();
}
}
}
This is okay - ish.
It's best not to reinvent the wheel.
1) There are blocking queues which have methods to wait for new items and are already synchronized:
public static void main(String[] args) throws Exception {
final BlockingQueue<Runnable> r = new LinkedBlockingQueue<>();
final Thread t = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
try {
r.take().run();
} catch (InterruptedException ex) {
return;
}
}
}
});
r.add(new Runnable() {
#Override
public void run() {
//do stuff
}
});
}
2) There is the ExecutorService API which encapsulates all this behaviour:
public static void main(String[] args) throws Exception {
final ExecutorService es = Executors.newSingleThreadExecutor();
es.execute(new Runnable() {
#Override
public void run() {
//do stuff
}
});
}
3) If you want to check the success of the submitted task and/or wait for a sumbitted task to finish you cannot do that using your API. With the ExecutorService you can do this very easily.
public static void main(String[] args) throws InterruptedException {
final ExecutorService es = Executors.newSingleThreadExecutor();
final Future<?> f = es.submit(new Runnable() {
#Override
public void run() {
//do stuff
}
});
try {
//wait
f.get();
} catch (ExecutionException ex) {
//there was an exeception in the task
}
}
A final note is that the way you have implemented your code there is no way to stop the consumer thread.
In my first example you would need to manually call t.interrupt() and because of my implementation this would case the thread to exit. In the second/third examples you would need to call ExecutorService.shutdown() to stop the consumer threads.
If you do not stop the threads then your program will not exit unless they are daemon.
Why are you making your own implementation? Java has a built-in ExecutorService that can run Runnables on a single thread http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
//runs all Runnables in a single thread, one at a time
ExecutorService executor = Executors.newFixedThreadPool(1);
executor.submit(runnable);
Here are few improvements... Of-course if you use BlockingQueue/ExecutorService we don't need to worry about synchronization/concurrency.
One main issue in the code is: "r.run()" instead of new Thread(r).start().
Use ConcurrentLinkedQueue data structure which is Thread safe.
You can offer to lock/notify on any static obj/class obj, need not be on the queue, as queue is already thread safe.
Queue to Array conversion is not needed. iterate for queue.poll().
Also you can also use concurrent locks API (ReentrantLock or Condition classes) instead of synchronized/wait/notify.
theexamtime.com

Categories

Resources