I'm starting off with a very simple example in multithreading. I'm trying to make a threadsafe counter. I want to create two threads that increment the counter intermittently to reach 1000. Code below:
public class ThreadsExample implements Runnable {
static int counter = 1; // a global counter
public ThreadsExample() {
}
static synchronized void incrementCounter() {
System.out.println(Thread.currentThread().getName() + ": " + counter);
counter++;
}
@Override
public void run() {
while(counter<1000){
incrementCounter();
}
}
public static void main(String[] args) {
ThreadsExample te = new ThreadsExample();
Thread thread1 = new Thread(te);
Thread thread2 = new Thread(te);
thread1.start();
thread2.start();
}
}
From what I can tell, the while loop right now means that only the first thread has access to the counter until it reaches 1000. Output:
Thread-0: 1
.
.
.
Thread-0: 999
Thread-1: 1000
How do I fix that? How can I get the threads to share the counter?
How to make Thread-Safe code in Java. There are multiple ways to make this code thread-safe in Java: 1) Use the synchronized keyword in Java and lock the getCount() method so that only one thread can execute it at a time which removes the possibility of coinciding or interleaving.
Example of Non-Thread-Safe Code in Java The above example is not thread-safe because ++ (the increment operator) is not an atomic operation and can be broken down into reading, update, and write operations.
There is no rule that makes the code thread safe, the only thing you can do is make sure that your code will work no matter how many times is it being actively executed, each thread can be interrupted at any point, with each thread being in its own state/location, and this for each function (static or otherwise) that ...
A thread-safe class is a class that guarantees the internal state of the class as well as returned values from methods, are correct while invoked concurrently from multiple threads. The collection classes that are thread-safe in Java are Stack, Vector, Properties, Hashtable, etc.
You could use the AtomicInteger
. It is a class that can be incremented atomically, so two seperate threads calling its increment method do not interleave.
public class ThreadsExample implements Runnable {
static AtomicInteger counter = new AtomicInteger(1); // a global counter
public ThreadsExample() {
}
static void incrementCounter() {
System.out.println(Thread.currentThread().getName() + ": " + counter.getAndIncrement());
}
@Override
public void run() {
while(counter.get() < 1000){
incrementCounter();
}
}
public static void main(String[] args) {
ThreadsExample te = new ThreadsExample();
Thread thread1 = new Thread(te);
Thread thread2 = new Thread(te);
thread1.start();
thread2.start();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With