I'm writing a program in Java that will allow a person to input data into a form as jobs for a help desk. The submitted form is then used to create a helpRequest object which is entered into a generic Queue for storage in a binary file. However, the onus of the project (it's a school assignment) is to make the program failsoft using exceptions. One specific stipulation of the program is that it must handle any situation where it cannot continue by attempting to save the current helpRequest queue before terminating "gracefully". I've got all of this set up in code, but when the handler runs (by a division by zero in my test), the program hangs as soon as it tries to do anything with the helpQueue.
I've tried looking up Java global variables and global exception handlers, but nothing seems to address the topic of using a structure or variable from another/the throwing class.
Here is the code for the handler. I have helpQueue declared as public and static in the throwing class HelpDeskForm, and NetBeans accepts all the code I have here. The induced exception occurs after the queue has been worked with.
public class GlobalExceptionHandler implements Thread.UncaughtExceptionHandler {
BinaryOutputFile emergencyOutput;
public void uncaughtException(Thread t, Throwable e) {
Frame f = new Frame();
JOptionPane.showMessageDialog(f, "Program error. Please select a file for queue output.");
emergencyOutput = new BinaryOutputFile();
while(!HelpDeskForm.helpQueue.isEmpty())
emergencyOutput.writeObject(HelpDeskForm.helpQueue.remove());
emergencyOutput.close();
System.exit(1);
}
}
Rather than a specific solution to my issue, I'd appreciate it if someone could explain why helpQueue is seemingly not actually visible/usable in this exception handler, or what I'm doing horribly wrong.
EDIT: I didn't want to overcomplicate my explanation, but here is the HelpDeskForm code up until my division by zero exception.
public class HelpDeskForm {
BinaryDataFile input;
BinaryOutputFile output;
CheckedForm c;
helpRequest r;
public static Queue<helpRequest> helpQueue;
int inputSize;
public HelpDeskForm() {
GlobalExceptionHandler h = new GlobalExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(h);
input = new BinaryDataFile();
inputSize = input.readInt();
for(int i = 0; i < inputSize; i++) {
helpQueue.add((helpRequest)input.readObject());
}
input.close();
int y = 0;
int z = 2;
z = z/y;
... // GUI code follows
}
}
HelpDeskForm seems to lack initialization for queue being used, so NPE is inevitable. Try to add initialization to declaration:
public static Queue<helpRequest> helpQueue = new ArrayBlockingQueue<helpRequest>(100);
Plus, for the posted code, it would be logical to add volatile keyword to queue declaration:
public static volatile BlockingQueue<helpRequest> helpQueue;
public void createQueue() {
// make sure createQueue() is called at the very beginning of your app,
// somewhere in main()
helpQueue = new ArrayBlockingQueue...
}
This way all other threads, if any, will see correct reference to the queue, and thread safety of BlockingQueue guarantees correct visibility of its' contents.
Related
This question already has answers here:
How should I unit test multithreaded code?
(29 answers)
Closed 5 years ago.
How do I test something like this in multithreaded environment. I know it's gonna fail, cause this code is not thread-safe. I just wanna know how can i prove it? Creating bunch of threads and trying to add with those different threads? This code is intentionally not written properly cause of testing purposes !!!
public class Response_Unit_Manager {
private static HashMap<String, Response_Unit> Response_Unit_DB =
new HashMap<> ();
/**
*
* This subprogram adds a new Response_Unit to the data store. The
* new response unit must be valid Response_Unit object and it's ID must be
* unique (i.e., must not already exist in the data store.
*
* Exceptions Thrown: Null_Object_Exception
*/
public static void Add_Response_Unit (Response_Unit New_Unit)
throws Null_Object_Exception, Duplicate_Item_Exception {
String Unit_ID = New_Unit.Unit_ID ();
if (New_Unit == null)
throw new Null_Object_Exception ();
else if (Response_Unit_Exists (Unit_ID))
throw new Duplicate_Item_Exception (Unit_ID);
else
Response_Unit_DB.put (Unit_ID, New_Unit);
} //end Add_Response_Unit
You may get lucky and see a failure when running a test, but non-failing code doesn't mean that it's thread-safe code. The only automated ways to check thread-safety is with some static analysis tools that let you put annotations on methods/classes and scan for potential issues. For example, I know FindBugs support some annotations and does concurrency checking based on them. You should be able to apply this to your single Tester class. There is still a lot of room for improvement in the industry on this topic, but here are some current examples:
http://robertfeldt.net/publications/grahn_2010_comparing_static_analysis_tools_for_concurrency_bugs.pdf
http://homepages.inf.ed.ac.uk/dts/students/spathoulas/spathoulas.pdf
As others have noted, you can't write a test that will guarantee failure as the thread schedule might "just work out", but you can write tests that have a very low probability of passing if there are thread safety issues. For example, you're code attempts to disallow duplicate items in your DB but due to thread safety issues it can't do that. So spawn a ton of threads, have them all wait on a CountdownLatch or something to maximize your chances of triggering the race, then have them all try to insert the same item. Finally you can check that (a) all but one thread saw a Duplicate_Item_Exception and (b) Response_Unit_DB contains only a single item. For these kinds of tests you can also run it several times (in the same test) to maximize your chances of triggering the issue.
Here's an example:
#Test
public void testIsThreadSafe() {
final int NUM_ITERATIONS = 100;
for(int i = 0; i < NUM_ITERATIONS; ++i) {
oneIsThreaSafeTest();
}
}
public void oneIsThreadSafeTest() {
final int NUM_THREADS = 1000;
final int UNIT_ID = 1;
final Response_Unit_Manager manager = new Response_Unit_Manager();
ExecutorService exec = Executors.newFixedThreadPool(NUM_THREADS);
CountdownLatch allThreadsWaitOnThis = new CountdownLatch(1);
AtomicInteger numThreadsSawException = new AtomicInteger(0);
for (int i = 0; i < NUM_THREADS; ++i) {
// this is a Java 8 Lambda, if using Java 7 or less you'd use a
// class that implements Runnable
exec.submit(() -> {
allThreadsWaitOnThis.await();
// making some assumptions here about how you construct
// a Response_Unit
Response_Unit unit = new Response_Unit(UNIT_ID);
try {
manager.Add_Response_Unit(unit);
} catch (Duplicate_Item_Exception e) {
numThreadsSawException.incrementAndGet();
}
});
// release all the threads
allThreadsWaitOnThis.countdown();
// wait for them all to finish
exec.shutdown();
exec.awaitTermination(10, TimeUnits.MINUTES);
assertThat(numThreadsSawException.get()).isEqualTo(NUM_THREADS - 1);
}
You can construct similar tests for the other potential thread safety issues.
The easiest way to find errors with testing, like the one which is contained in your class, is to use a Testrunner like for example the following:
package com.anarsoft.mit;
import java.util.concurrent.atomic.AtomicInteger;
public class Test_Response_Unit_Manager implements Runnable {
private final AtomicInteger threadCount = new AtomicInteger();
public void test() throws Exception
{
for(int i = 0; i < 2 ;i++)
{
Thread thread = new Thread(this, "Thread " + i);
this.threadCount.incrementAndGet();
thread.start();
}
while( this.threadCount.get() > 0 )
{
Thread.sleep(1000);
}
Thread.sleep(10 * 1000);
}
public void run()
{
exec();
threadCount.decrementAndGet();
}
protected void exec()
{
Response_Unit_Manager.Add_Response_Unit(new Response_Unit(Thread.currentThread().getId()));
}
public static void main(String[] args) throws Exception
{
(new Test_Response_Unit_Manager()).test();
}
}
And to use a dynamic race condition detection tool like http://vmlens.com, a lightweight race condition detector. This will show you the following race conditions:
And the stacktraces leading to the bug. On the left the write and one the right the read.
http://vmlens.com works with eclipse, so it depens on the ide you are using, if its useful for you
Having this simple class, with addition method :
class A {
public Integer add (int a, int b){
return a+b;
}
}
is it thread safe or not..? it looks safe for me, but most poeple answer no, could anyone explain why?
Thread safety should be bothered about only when you have some means of sharing state and you modify that without any locks or synchronization i.e. you modify a shared variable(class level variable) then only you should care about thread safety.
Here there is no issue of thread safety.
And in this particular case each variable is local and that location will not be shared by threads as each function call will have their on separate allocation on stack along with their local variables you should not bother anyways :)
It is completely thread safe, because all variables are local.
Actually that method is not thread safe, but it requires you to know a bit about the internals of the Integer class to understand why. Let's look at some code that yields the same bytecode:
class A {
public Integer add (int a, int b){
// auto boxing hidden in OP's implementation
return Integer.valueOf(a+b);
}
}
For small enough values the Integers are cached and looked up in a array. Using reflection you can access that array and change it's elements. Those changes are not synchronized, therefore if you change those elements, from another thread the result of your method can change too.
The following code should demonstrate the problem on most java VMs: There is a race condition in your method. In most cases it will print 4s and 5s:
import java.lang.reflect.Field;
class A {
public Integer add(int a, int b) {
return a + b;
}
private static volatile boolean cont = true;
public static void main(String[] args) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException, InterruptedException {
final A a = new A();
new Thread(() -> {
while(cont) {
for (int i = 0; i < 100; i++) {
// print result of add method
System.out.println(a.add(2,2));
}
}
}).start();
// give other thread time to start
Thread.sleep(1);
// mess around with the internals of Integer
Class cache = Integer.class.getDeclaredClasses()[0];
Field c = cache.getDeclaredField("cache");
c.setAccessible(true);
Integer[] array = (Integer[]) c.get(cache);
array[132] = array[133];
cont = false;
}
}
However in most cases nobody messes around with the internals of Integer. If the array in the Integer class is never modified, the values wrapped by the Integer objects returned by your method will always be correct, since the shared state used by Integer.valueOf is never modified. Therefore it would be thread-safe in that case.
I have a class X, classMachine, class Z, all of them are Threads. When Machine threads are initialized, they are put on a BlockingQueue firstQueue. Inside machines' run method there is a while loop which checks if its boolean variable should be true or false. When it is true, machine should be put on BlockingQueue secondQueue
secondQueue.put(this);
and Z class can take it from there. If machine thread returns false, class X can take machine from firstQueue and work on it.
Now, my question is: when boolean is true, is it possible to make Machine take itself from firstQueue?
PS.I know that the question might be unclearly asked, but I don't know how to form it properly. If anyone knows to make it better, please correct it.
EDIT.
Code samples.
Here is a part from class that starts all the threads, all the queues are initialized of course.
public class Machine implements Runnable{
private final BlockingQueue firstQueue;
private final BlockingQueue secondQueue;
boolean broken;
public Machine(...){...}
public void run() {
while(true){
//use Rand (min=0, max=1) and define if(random==1)broken=true else broken=false
if(broken==true){
Machine multi = fistQueue.take(this);//here is problem!!!!!
secondQueue.put(this);
}
}
}...}
and part form class that starts the threads
//machines should have an ability to take themselves from queue when broken==true, and then put on secondQueue
BlockingQueue<Machine> firstQueue = new ArrayBlockingQueue<Machine>(10);
service=Executors.newFixedThreadPool(10);
for(int k=0; k < 10; k++){
Machine M= new Machine(secondQueue, k);
firstQueue.add(M);
service.submit(M);
}
//X can take machines from firstQueue, and work on them if broken==false
Thread XThread = new Thread(new X(firstQueue));
XThread.start();
//takes machines form secondQueue
Thread ZThread = new Thread(new Z(secondQueue));
ZThread.start();
EDIT2
public class X implements Runnable(){
//fields, constructor
public void run() {
while(true){
machine=machines.take();
if(machine.broken==true){
//leave this machine (it should be on , and take other which is fine_
}
while(machine.broken==false){
machine.pass(record); // (Record record=new Record(task, result field);
//do Your thing
}
if(result==initialResultFromX){
//means it got broken while working and needs to take a new machine
}
}...
}
First of, this answer aims to help improve the design of the solution, which in turn might answer the actual question. However, if OP is happy with the current design, I believe the question can be answered by removing the following line:
Machine multi = fistQueue.take(this);
So,
Is it possible to make Machine take itself from firstQueue?
There is no method to directly get an object inside the queue without removing it (As stated in the comments, the machine should not be removed from the first queue). Because you can access the instance of the machine by using this, secondQueue.put(this) would suffice in adding the Machine to the second queue.
I might be interpreting your design wrong, but it seems to me that each Machine has a state. This state depends whether or not the Machine can or cannot execute whatever it must execute. If this is true, I believe it isn't wise to keep the handling of state changes in the machine itself(adding/removing itself to different executing queues).
You need an abstraction of some sort. Lets called this your StateMachine. The StateMachine creates, manages and handles state changes of each Machine, by implementing some listening interface. This will allow each machine to report any events or problems to the StateMachine. The StateMachine can then determine how to handle events.
I'll try to explain by example. Here is the interface that the StateMachine will implement:
public interface BrokenListener {
public void onBrokenEvent(Object machine);
}
This allows communications between the StateMachine and each Machine. However, this requires an instance of the StateMachine to be passed to each machine instead of the queues.
for(int k=0; k < 10; k++){
Machine m = new Machine(this); //where this is the StateMachine
firstQueue.add(m);
}
Once a Machines state changes from broken == false to broken == true, the onBrokenEvent() can be called.
public class Machine {
/* The listener */
private BrokenListener listener;
private boolean broken = false;
public Machine(BrokenListener listener) {
this.listener = listener;
}
/* When the state of the machine changes */
public void setBroken(boolean broken) {
this.broken = broken;
if (this.broken) {
//Here we pass the current Machine to the StateMachine. How the event is handled should not be up to the machine.
this.listener.onBrokenEvent(this);
}
}
}
Here is the StateMachine:
public class StateMachine implements BrokenListener {
#Override
public void onBrokenEvent(Object machine) {
if (machine instanceof Machine) {
second.add((Machine) machine);
}
}
}
As you can see, when the state machine implements the onBrokenEvent method. When this method is called by the Machine, it can be added to the second queue for processing.
I assume the X and Y classes will do the processing, so you still need to pass the queues to them.
Thread XThread = new Thread(new X(firstQueue));
XThread.start();
Thread ZThread = new Thread(new Z(secondQueue));
ZThread.start();
What makes this nice is, it keeps the logic used for handling state changes out of the Machine.
Feel free to ask any questions.
I am doing some personal research for examinations. Past exams have asked Outline how a partially initialised object in Java is vulnerable to exploitation. and also, What are the possible complications of somebody exploiting said Objects in your application
Now, i found this resource here: securecoding.cert
On the above website, i can see examples as to how its done, but i can't seem to see or understand the purpose of it, what can you actually maliciously do with such Objects.
From what i understand, you should always check that Object instantiation has completed when performing operations (e.g. Boolean or similar) like so;
class BankAccount {
private int balance; // Defaults to 0
private volatile boolean initialized = false;
public BankAccount() {
if (!performAccountVerification()) {
throw new SecurityException("Invalid Account");
}
balance = 1000;
// ...
initialized = true;
}
public int getBalance() {
if (!initialized) {
throw new IllegalStateException("Class not initialized");
}
return balance;
}
// ...
}
Code taken from the above resource.
You should also use volatile, as you want to ensure synchronisation because part of the problem is the fact that the Java Memory allows other Threads to access these Partially Initialised Objects.
So in summary:
Why would you want to do this?
What can you actually do with these Objects
Should you always be concerned about this, or only in critical systems?
Thanks,
Chris.
Well, if I don't have access to a bank account, and your class isn't checking that initialized flag, I could theoretically be able to do something like this:
class Thief extends Thread {
public BankAccount ba = null;
void run() {
do {
if(ba != null) ba.transferAllMoneyToDima();
} while(ba == null);
}
}
Thief th = new Thief();
th.start();
th.ba = new BankAccount();
What happens here is that BankAccount constructor is supposed to verify that I have access to the account, and throw an exception if not. By optimizer is allowed to reorder certain operations. In particular, it can assign the object to th.ba immediately after it is allocated, before the constructor completes. If that happens, my Thief thread will see the non-null value, and steal of the money before the vertification completes and determines that I should not have been allowed to do this.
I have an Arraylist that I am constantly adding to and removing from in separate threads.
One thread adds, and the other removes.
This is the class that contains the changing list:
public class DataReceiver {
private static final String DEBUG_TAG = "DataReceiver";
// Class variables
private volatile ArrayList<Byte> buffer;
//private volatile Semaphore dataAmount;
public DataReceiver() {
this.buffer = new ArrayList<Byte>();
//this.dataAmount = new Semaphore(0, true);
}
// Adds a data sample to the data buffer.
public final void addData(byte[] newData, int bytes) {
int newDataPos = 0;
// While there is still data
while(newDataPos < bytes) {
// Fill data buffer array with new data
buffer.add(newData[newDataPos]);
newDataPos++;
//dataAmount.release();
}
return;
}
public synchronized byte getDataByte() {
/*
try {
dataAmount.acquire();
}
catch(InterruptedException e) {
return 0;
}
*/
while(buffer.size() == 0) {
try {
Thread.sleep(250);
}
catch(Exception e) {
Log.d(DEBUG_TAG, "getDataByte: failed to sleep");
}
}
return buffer.remove(0);
}
}
The problem is I get a null pointer every so often exception when trying to buffer.remove(0). As you can tell form the comments in the code, I tried using a semaphore at one point but it still intermittently threw nullpointer exceptions, so I created my own type of sleep-poll as a semi-proof-of-concept.
I do not understand why a null pointer exception would occur and/or how to fix it.
If you are handling the object initialization in a different thread it is possible that the constructor is not finished before the
public synchronized byte getDataByte()
is called therefore causing the NullPointerException because
this.buffer = new ArrayList<Byte>();
was never called.
I have a guess as to an explanation. I would do it in comments, but I don't have enough reputation, so hopefully this answer is helpful.
First of all, if you were to declare the addData() function as synchronized, would your problem go away? My guess is that it would.
My theory is that although you declared buffer as volatile, that is not sufficient protection for your use case. Imagine this case:
addData() gets called and is calling buffer.add()
at the same time, getDataByte() is checking buffer.size() == 0
My theory is that buffer.add() is not an atomic operation. Somewhere during the buffer.add() operation, it's internal size counter increments, enabling your getDataByte() call to buffer.size() == 0 to return false. On occasion, getDataByte() continues with its buffer.remove() call before your buffer.add() call completes.
This is based on an excerpt I read here:
https://www.ibm.com/developerworks/java/library/j-jtp06197/
"While the increment operation (x++) may look like a single operation, it is really a compound read-modify-write sequence of operations that must execute atomically -- and volatile does not provide the necessary atomicity."