Is jBCrypt 0.3 threadsafe? - java

Question says it all really. Code can be found at the following link -> http://www.mindrot.org/projects/jBCrypt/

I strongly disagree with the existing answers, and the currently-accepted answer.
After a brief review of the source code for jBcrypt, I'm satisfied that it is thread-safe. The only instance created does not escape the scope of the key hashpw static method, and its fields are not shared with any other instances through any mechanism that I can see.
Further, I'm really confused by the complaints about the API consisting of static methods. Hashing functions are pure, and so there is no reason to not provide them via static methods. I'm actually quite glad that there is no usable userland access to instance methods, lest some fool try to do something clever (like using one instance over and over, "resetting" it to minimize allocation/GC or some such silliness).

Resurrecting this old issue because I believe the current answers are wrong and this thread pops high in google searches.
Looked at the code and ran a couple of simple tests. jbcryt appears to be thread safe.
In the code:
-although it has mostly static method, those methods create instances of the bcrypt class to do computations when needed.
Test samples:
-had bcrypt not been thread safe, I would have expected either of these methods to throw some form of error, which they did not.
#Test
public void multiThreadHash() throws InterruptedException{
List<Thread> threads = new ArrayList<Thread>();
for(int i = 0; i<40; i++){
threads.add(new Thread(){
#Override
public void run() {
long start = System.currentTimeMillis();
while(System.currentTimeMillis()<start+12000){
String password = "sample";
String hash = BCrypt.gensalt(4);
String hashed = BCrypt.hashpw(password, hash);
}
}
});
}
for(Thread t: threads){
t.start();
}
Thread.sleep(12200L);
}
#Test
public void multiThreadReproductibleHash() throws InterruptedException{
List<Thread> threads = new ArrayList<Thread>();
for(int i = 0; i<40; i++){
threads.add(new Thread(){
#Override
public void run() {
long start = System.currentTimeMillis();
while(System.currentTimeMillis()<start+12000){
String password = "sample";
String hash = "$2a$04$/YkrS2ifyAloNVUk5qAO7O";
String expected = "$2a$04$/YkrS2ifyAloNVUk5qAO7OlqIsp2ECTMDinOij9wvn7nXPRJCo8Gy";
String hashed = BCrypt.hashpw(password, hash);
Assert.assertEquals(expected, hashed);
}
}
});
}
for(Thread t: threads){
t.start();
}
Thread.sleep(12200L);
}

First, it's not documented as thread-safe, so for all intents and purposes, it's not. And, on further investigation, it's definitely not: It turns out that, while there are some instance fields, there is no instance of BCrypt exposed; it tries to do everything through static methods. It may not be thread safe. It's small enough that, assuming you care and the author would accept, you could offer a patch to trivially convert it to provide separate, safe instances (edit to add: I have scrubbed it carefully and prepared a cleaner version, which I will send to the author...)
Second, in what manner do you want to use this in a multithreaded environment? It's not clear to me what you'd want to do in separate threads.
NOTE: There is a dissenting opinion below with more upvotes as of 7/18/2013

Related

How to solve race condition of two writers using immutable objects

I was thinking about how to solve race condition between two threads which tries to write to the same variable using immutable objects and without helping any keywords such as synchronize(lock)/volatile in java.
But I couldn't figure it out, is it possible to solve this problem with such solution at all?
public class Test {
private static IAmSoImmutable iAmSoImmutable;
private static final Runnable increment1000Times = () -> {
for (int i = 0; i < 1000; i++) {
iAmSoImmutable.increment();
}
};
public static void main(String... args) throws Exception {
for (int i = 0; i < 10; i++) {
iAmSoImmutable = new IAmSoImmutable(0);
Thread t1 = new Thread(increment1000Times);
Thread t2 = new Thread(increment1000Times);
t1.start();
t2.start();
t1.join();
t2.join();
// Prints a different result every time -- why? :
System.out.println(iAmSoImmutable.value);
}
}
public static class IAmSoImmutable {
private int value;
public IAmSoImmutable(int value) {
this.value = value;
}
public IAmSoImmutable increment() {
return new IAmSoImmutable(++value);
}
}
If you run this code you'll get different answers every time, which mean a race condition is happening.
You can not solve race condition without using any of existence synchronisation (or volatile) techniques. That what they were designed for. If it would be possible there would be no need of them.
More particularly your code seems to be broken. This method:
public IAmSoImmutable increment() {
return new IAmSoImmutable(++value);
}
is nonsense for two reasons:
1) It makes broken immutability of class, because it changes object's variable value.
2) Its result - new instance of class IAmSoImmutable - is never used.
The fundamental problem here is that you've misunderstood what "immutability" means.
"Immutability" means — no writes. Values are created, but are never modified.
Immutability ensures that there are no race conditions, because race conditions are always caused by writes: either two threads performing writes that aren't consistent with each other, or one thread performing writes and another thread performing reads that give inconsistent results, or similar.
(Caveat: even an immutable object is effectively mutable during construction — Java creates the object, then populates its fields — so in addition to being immutable in general, you need to use the final keyword appropriately and take care with what you do in the constructor. But, those are minor details.)
With that understanding, we can go back to your initial sentence:
I was thinking about how to solve race condition between two threads which tries to write to the same variable using immutable objects and without helping any keywords such as synchronize(lock)/volatile in java.
The problem here is that you actually aren't using immutable objects: your entire goal is to perform writes, and the entire concept of immutability is that no writes happen. These are not compatible.
That said, immutability certainly has its place. You can have immutable IAmSoImmutable objects, with the only writes being that you swap these objects out for each other. That helps simplify the problem, by reducing the scope of writes that you have to worry about: there's only one kind of write. But even that one kind of write will require synchronization.
The best approach here is probably to use an AtomicReference<IAmSoImmutable>. This provides a non-blocking way to swap out your IAmSoImmutable-s, while guaranteeing that no write gets silently dropped.
(In fact, in the special case that your value is just an integer, the JDK provides AtomicInteger that handles the necessary compare-and-swap loops and so on for threadsafe incrementation.)
Even if the problems are resolved by :
Avoiding the change of IAmSoImmutable.value
Reassigning the new object created within increment() back into the iAmSoImmutable reference.
There still are pieces of your code that are not atomic and that needs a sort of synchronization.
A solution would be to use a synchronized method of course
public synchronized static void increment() {
iAmSoImmutable = iAmSoImmutable.increment();
}
Thread t1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
increment();
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
increment();
}
});

10 threads write to single hash simultaniously

Sorry for the question(( I just have stuck in the end of the day((
I need for test 10 threads writing to the same hash (really not a hash but very similar thing i need to prove it synchronization for write)
is this is right code?
Random rn = new Random();
Map<int,int> hash = new MyHashMap<int,int>();
for(int i = 0; i< 10; i++)
{
Thread th = new MyAddingThread();
th.Start();
}
public class MyAddingThread extends Thread{
public void run()
{
hash.Add(rn.nextInt,rn.nextInt);
}
}
May be better to change 10 to 100. but I have no idea how to test dat hash for synchronization(
HashMap is not thread-safe. Use a ConcurrentHashMap instead.
EDIT
If your real question is whether your code will allow you to test whether any given data structure is thread-safe or not, there really is no reliable way to do so. Multi-thread development can introduce any number of bugs that can be extremely difficult to detect. A data structure is either designed to be thread-safe, or it is not.
That won't work, as all threads should try to add the item to the hash at the same time.
To do that, you need to use a CountDownLatch
[[main]]
CountDownLatch startSignal = new CountDownLatch(1);
for(int i = 0; i< 10; i++)
{
Thread th = new MyAddingThread();
th.Start();
}
startSignal.countdown();
[[on the thread]]
public class MyAddingThread extends Thread{
public void run()
{
startSignal.await();
hash.Add(rn.nextInt,rn.nextInt);
}
}
The javadoc of this class has a similar (but more complex) example.
Also, if you want to test this properly, create the same number of threads as cores in your computer and each thread should do a loop and insert a few hundred items at least. if you try to only insert 10 elements, there are very little chances that you'll hit a concurrent problem.
A HashMap is not synchronized so you have to do it on your own!
You may synchronize the access:
public class MyAddingThread extends Thread {
public void run() {
synchronized(hash) {
hash.put(rn.nextInt(),rn.nextInt());
}
}
}
but than you miss most of the concurrent execution.
Another idea is to use a ConcurrentHashMap:
ConcurrentMap<Integer,Integer> hash = new ConcurrentHashMap<>();
public class MyAddingThread extends Thread {
public void run() {
hash.put(rn.nextInt(),rn.nextInt());
}
}
This would give more performance due to less blocking code.
The other problem is the use of Random here which is thread safe but will also result in poor performance.
Which solution is the best for your problem I cannot consider from your little pseudo code.

Java: Do all static methods need to be synchronized?

I have a friend who said that all static methods should be synchronized in the context of a Java web application. Is that true? I have read many other stack overflow pages regarding this. What I have come to believe is that you only need to synchronize if you have:
Multiple Threads (As in a Sevlet Container with a thread pool)
Single ClassLoader
Shared data between threads, whether it is Session data or static member data.
Shared data must be mutable. Read only data is ok to share.
Based on this I think that static members should be synchronized, but not static methods.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadTest {
static String staticString = "";
// This static method is safe b/c it only uses local data.
// It does not use any shared mutable data.
// It even uses a string builder.
static String safeStaticMethod(String in) {
// This also proves that StringBuilder is safe
// When used locally by a thread.
StringBuilder sb = new StringBuilder();
sb.append("Hello: ");
sb.append(in);
return sb.toString();
}
// This static method is not safe b/c it updates and reads
// shared mutable data among threads.
// Adding synchronized will make this safe.
static String unsafeStaticMethod(String in) {
staticString = in;
StringBuffer sb = new StringBuffer();
sb.append("Hello: ");
sb.append(staticString);
return sb.toString();
}
public static void main(String[] args) {
ThreadTest test = new ThreadTest();
test.staticMethodWithLocalData();
test.staticMethodWithStaticData();
}
public void staticMethodWithLocalData() {
ExecutorService executor = Executors.newFixedThreadPool(2);
final int iterations = 100000;
executor.submit(new Runnable() {
#Override
public void run() {
for (int index = 0; index < iterations; ++index) {
if (!safeStaticMethod("Thread1").equals("Hello: Thread1")) {
System.out.println("safeStaticMethod at " + index);
}
}
}
});
executor.submit(new Runnable() {
#Override
public void run() {
for (int index = 0; index < iterations; ++index) {
if (!safeStaticMethod("Thread2").equals("Hello: Thread2")) {
System.out.println("safeStaticMethod at " + index);
}
}
}
});
}
public void staticMethodWithStaticData() {
ExecutorService executor = Executors.newFixedThreadPool(2);
final int iterations = 100000;
executor.submit(new Runnable() {
#Override
public void run() {
for (int index = 0; index < iterations; ++index) {
if (!unsafeStaticMethod("Thread1").equals("Hello: Thread1")) {
System.out.println("unsafeStaticMethod at " + index);
}
}
}
});
executor.submit(new Runnable() {
#Override
public void run() {
for (int index = 0; index < iterations; ++index) {
if (!unsafeStaticMethod("Thread2").equals("Hello: Thread2")) {
System.out.println("unsafeStaticMethod at " + index);
}
}
}
});
}
}
Does this code prove the point?
EDIT: This is only some throwaway code I hacked up to prove the point.
No, not all static methods need to be synchronized. Your list is basically complete as far as I can see. Be particularly careful when the static method either
accesses a static member that is mutable, or
gets passed a reference to an object that can be modified.
I think it goes without saying that 1 (having threads in the first place) is a precondition, since without threads synchronize makes no sense.
I've never heard 2, so I don't know for sure if it's a consideration.
No that's not true and I'm sure it would be detrimental. Not every application needs to be concurrent, and even in applications that do need to be concurrent, not every piece of code has to be.
As more evidence, look at the source of String. There are many static methods in there, but I could only find one synchronized method, and that one isn't even static.
Static methods should almost never be synchronized in a webapp. Unless you are 100% sure that the only people who will ever use the application are your 3 person accounting team, and willing to be red in the face if it takes off company-wide and all of the sudden grinds to a near halt.
Creating a global, blocking, shared resource is a total failure in scalability! It's also going to cause you lots of headaches and likely lock you into a Terracotta style solution if you end up needing to cluster the application server.
In a web application(like one build using the servlet/JSP), you should always avoid making a method as synchronized as it challenges the whole philosophy of mutli-thread accessibility. In place, always try to place the only necessary code, which needs to be accessed one by one, inside the synchronized block.
Not at all. Mostly, the static methods that I have come across do not modify any static variables and hence they do not require to be synchronized.
For simple understanding,
//sample static util method to get string in upper case
public static String getName(String name){
return a.toUpperCase();
}
The above method can be called by 1000s of threads and yet it is going to be thread-safe because the method only requires an argument- String name and that is from the Thread Stack. It is not shared data between threads.
Think about it, if all the static methods were synchonized, the web-applications shall be extremely slow and lethargic to use. We shall have class-level lock whenever a single thread tries to access the method.
There are a lot of static methods in the APIs provided by JDK. If all those were synchronized, am pretty sure we wouldn't be using JAVA.
In your case, there is a static variable(class level variable) that is being modified by the static method. Yes, if multiple threads are created and they are going to access the static method, there is a possibility of Thread Interference. It is not thread-safe as there is shared data between them.
Mostly, the static methods are utility functions depending on the arguments being passed to them.
Please note that non-synchronized static methods are thread safe if they don't modify static class variables.

Read and write from global variables

What I'm trying to do is have a global variable classes and function can read/write from/to.
What I have now is
import java.lang.*;
import lab1.Global;
public class SecondProgram {
public static void main ( String args[] ) {
System.out.println("hi ");
Global.b[0] = " zero ";
Global.b[1] = " One ";
Global.b[2] = " Two ";
Global.b[3] = " Three ";
}
}
and I created a class to store the global variables
public class Global {
public static String a = "hi" ;
public static String [] b;
}
Of course it is important that the size of the array isn't a hardcoded constant but a variable I'll be able to find out at some point and plug in.
I hope you can see from the code what I'm trying to do, and you know how to make it work.
Thanks!
I want global variables because i am having threads read data from text files into arrays, and it's important that the arrays and their data stay present after the thread finishes its work.
Well that won't work. Or at least, it won't work reliably (and in a sense that is a worse outcome!)
In a multi-threaded Java program, you need to be sure that the threads synchronize properly at points where information gets passed from one to another. The purpose of the synchronization is twofold:
to prevent race conditions; i.e. where one thread tries to read a value before another one has read it, and
to ensure that threads don't see stale copies of values due to memory caching effects.
Synchronizing bare global variables is going to be fiendishly hard. My advice is
Pay attention to the comments (above) and design and implement using classes to encapsulate the state.
Use the utility classes in java.util.concurrent to implement the shared data structures ... and handle thread creation / management. Look at the ExecutorService API for example,
Get a good textbook on concurrent programming in Java. Concurrency in Java is not simple, and if you don't know what you are doing you can spend hours / days / weeks / months tracking down the causes of intermittent failures.
i think this is a far better approach and something to get you started....
import java.util.ArrayList;
public class SecondProgram {
private static ArrayList <String>file = new ArrayList();
public synchronized boolean writeFile(String str){
//wrtite file to your list
file.add(str);
return true;
}
public static void main(String args[]) {
//read file and use the synchronized method to write it to your list
}
}
I don't advocate the use of globals, but if you must, you can do something like the following. In general: have each thread build up its own data. When it is finished doing its work, add its data to a synchronized global collection (in this case, a List<List<String>>). Then read that collection once all of the threads have finished their work.
The global that collects the data:
public class GlobalDataBroker {
public static List<List<String>> data = Collections.synchronizedList(new LinkedList<List<String>>());
}
An example implementation:
public static void main(String[] args) throws InterruptedException {
for (int i=0; i < 10; i++) {
new Thread(new Runnable(){
#Override
public void run() {
List<String> list = new LinkedList<String>();
list.add(String.format("I'm a Thread and my name is %s.",Thread.currentThread()));
for (int i = 0; i < 5; i++) {
list.add("Data!");
}
GlobalDataBroker.data.add(list);
}
}).start();
}
// When the threads are done ...
Iterator<List<String>> i = GlobalDataBroker.data.iterator();
while (i.hasNext()) {
System.out.println(i.next());
}
}
Output:
[I'm a Thread and my name is Thread[Thread-8,5,main]., Data!, Data!, Data!, Data!, Data!]
[I'm a Thread and my name is Thread[Thread-5,5,main]., Data!, Data!, Data!, Data!, Data!]
...
[I'm a Thread and my name is Thread[Thread-7,5,main]., Data!, Data!, Data!, Data!, Data!]
Note that you should only begin iterating over your data once you've completed writing it. (Otherwise, you may encounter the dreaded ConcurrentModificationException.)

Thread-safe code without using the `synchronized` keyword?

What are the possible ways to make code thread-safe without using the synchronized keyword?
Actually, lots of ways:
No need for synchronization at all if you don't have mutable state.
No need for synchronization if the mutable state is confined to a single thread. This can be done by using local variables or java.lang.ThreadLocal.
You can also use built-in synchronizers. java.util.concurrent.locks.ReentrantLock has the same functionality as the lock you access when using synchronized blocks and methods, and it is even more powerful.
Only have variables/references local to methods. Or ensure that any instance variables are immutable.
You can make your code thread-safe by making all the data immutable, if there is no mutability, everything is thread-safe.
Secondly, you may want to have a look at java concurrent API which has provision for providing read / write locks which perform better in case there are lots of readers and a few writers. Pure synchronized keyword will block two readers also.
////////////FIRST METHOD USING SINGLE boolean//////////////
public class ThreadTest implements Runnable {
ThreadTest() {
Log.i("Ayaz", "Constructor..");
}
private boolean lockBoolean = false;
public void run() {
Log.i("Ayaz", "Thread started.." + Thread.currentThread().getName());
while (lockBoolean) {
// infinite loop for other thread if one is accessing
}
lockBoolean = true;
synchronizedMethod();
}
/**
* This method is synchronized without using synchronized keyword
*/
public void synchronizedMethod() {
Log.e("Ayaz", "processing...." + Thread.currentThread().getName());
try {
Thread.currentThread().sleep(3000);
} catch (Exception e) {
System.out.println("Exp");
}
Log.e("Ayaz", "complete.." + Thread.currentThread().getName());
lockBoolean = false;
}
} //end of ThreadTest class
//For testing use below line in main method or in Activity
ThreadTest threadTest = new ThreadTest();
Thread threadA = new Thread(threadTest, "A thead");
Thread threadB = new Thread(threadTest, "B thead");
threadA.start();
threadB.start();
///////////SECOND METHOD USING TWO boolean/////////////////
public class ThreadTest implements Runnable {
ThreadTest() {
Log.i("Ayaz", "Constructor..");
}
private boolean isAnyThreadInUse = false;
private boolean lockBoolean = false;
public void run() {
Log.i("Ayaz", "Thread started.." + Thread.currentThread().getName());
while (!lockBoolean)
if (!isAnyThreadInUse) {
isAnyThreadInUse = true;
synchronizedMethod();
lockBoolean = true;
}
}
/**
* This method is synchronized without using synchronized keyword
*/
public void synchronizedMethod() {
Log.e("Ayaz", "processing...." + Thread.currentThread().getName());
try {
Thread.currentThread().sleep(3000);
} catch (Exception e) {
System.out.println("Exp");
}
Log.e("Ayaz", "complete.." + Thread.currentThread().getName());
isAnyThreadInUse = false;
}
} // end of ThreadTest class
//For testing use below line in main method or in Activity
ThreadTest threadTest = new ThreadTest();
Thread t1 = new Thread(threadTest, "a thead");
Thread t2 = new Thread(threadTest, "b thead");
t1.start();
t2.start();
To maintain predictability you must either ensure all access to mutable data is made sequentially or handle the issues caused by parallel access.
The most gross protection uses the synchronized keyword. Beyond that there are at least two layers of possibility, each with their benefits.
Locks/Semaphores
These can be very effective. For example, if you have a structure that is read by many threads but only updated by one you may find a ReadWriteLock useful.
Locks can be much more efficient if you choose your lock to match the algorithm.
Atomics
Use of AtomicReference for example can often provide completely lock free functionality. This can usually provide huge benefits.
The reasoning behind atomics is to allow them to fail but to tell you they failed in a way you can handle it.
For example, if you want to change a value you can read it and then write its new value so long as it is still the old value. This is called a "compare and set" or cas and can usually be implemented in hardware and so is extremely efficient. All you then need is something like:
long old = atomic.get();
while ( !atomic.cas(old, old+1) ) {
// The value changed between my get and the cas. Get it again.
old = atomic.get();
}
Note, however, that predictability is not always the requirement.
Well there are many ways you can achieve this, but each contains many flavors. Java 8 also ships with new concurrency features.
Some ways you could make sure thread safety are:
Semaphores
Locks-Reentrantlock,ReadWriteLock,StampedLock(Java 8)
Why do u need to do it?
Using only local variable/references will not solve most of the complex business needs.
Also, if instance variable are immutable, their references can still be changed by other threads.
One option is use something like a SingleThreadModel, but it is highly discouraged and deprecated.
u can also look at concurrent api as suggested above by Kal

Categories