in my program I need to have multiple threads use and edit the same variable, but it doesn't seem to be working. Here is an example of what I mean, this would be my main class.
public class MainClass {
public static int number = 0;
public static String num = Integer.toString(number);
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Enter number of threads.");
int threads = in.nextInt();
for (int n = 1; n <= threads; n++) {
java.lang.Thread t = new Thread();
t.start();
}
}
}
This would be my Thread class:
public class Thread extends java.lang.Thread
{
public void run()
{
MainClass.number++;
System.out.println("Thread started");
System.out.println(MainClass.num);
}
}
I wrote this code on the spot, so there may be some errors, but thats ok. My program basically needs to do something like this, but instead of printing the number plus 1 every time, all the threads simply print the same number, 0, multiple times. Please help me, thanks.
In my program I need to have multiple threads use and edit the same variable, but it doesn't seem to be working...
Anytime multiple threads are updating the same variable you need to worry about memory synchronization. One of the ways that threads get high performance is because each thread utilizes the local CPU memory cache and so may be working with stale copies of variables. You need to use the synchronized or volatile keywords to force the thread's cache to write any updates to central storage or update its cache from central.
Although this takes care of memory synchronization, it doesn't necessarily protect you from race conditions. It is also important to realize that ++ is actually 3 operations: get the current value, increment it, and store it back again. If multiple threads are trying to do this, there are thread race-conditions which can cause the ++ operations to be missed.
In this case, you should use the AtomicInteger class which wraps a volatile int field. It gives you methods like incrementAndGet() which do the job of incrementing that field in a thread-safe manner.
public static AtomicInteger number = new AtomicInteger(0);
...
MainClass.number.incrementAndGet();
Multiple threads can then be incrementing the same variable safely.
Here You go...
import java.util.Scanner;
import java.util.concurrent.atomic.AtomicInteger;
public class UpdateVariables
{
static int num = 0;
public static AtomicInteger atomicInteger = new AtomicInteger(num);
#SuppressWarnings("resource")
public static void main(String args[])
{
Scanner userInput = new Scanner(System.in);
System.out.println("Enter Number of Threads: ");
int getThreadNumber = userInput.nextInt();
for(int i = 0; i < getThreadNumber; i++)
{
PrintThread p = new PrintThread();
p.start();
}
}
}
class PrintThread extends Thread
{
public void run()
{
System.out.println("Thread Started: ");
System.out.println(UpdateVariables.atomicInteger.incrementAndGet());
}
}
Related
I've read through the API documentation of the java.util.concurrent package, but have obviously misunderstood something. The overview says
A small toolkit of classes that support lock-free thread-safe
programming on single variables.
However, a small test application shows that the AtomicInteger class does not provide thread-safety, at least when it is shared across threads (I accept that the getAndSet / increment methods themselves are at least atomic)
Test:
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicIntTest
{
public static void main(String[] args) throws InterruptedException
{
AtomicInteger atomicInt = new AtomicInteger(0);
WorkerThread w1 = new WorkerThread(atomicInt);
WorkerThread w2 = new WorkerThread(atomicInt);
w1.start();
w2.start();
w2.join(); // <-- As pointed out by StuartLC and BarrySW19, this should be w1.join(). This typo allows the program to produce variable results because it does not correctly wait for *both* threads to finish before outputting a result.
w2.join();
System.out.println("Final value: " + atomicInt.get());
}
public static class WorkerThread extends Thread
{
private AtomicInteger atomicInt = null;
private Random random = new Random();
public WorkerThread(AtomicInteger atomicInt)
{
this.atomicInt = atomicInt;
}
#Override
public void run()
{
for (int i = 0; i < 500; i++)
{
this.atomicInt.incrementAndGet();
try
{
Thread.sleep(this.random.nextInt(50));
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
}
When I run this class, I consistently get results ranging from around 950 to 1000, when I would expect to always see exactly 1000.
Can you explain why do I not get consistent results when two threads access this shared AtomicInteger variable? Have I misunderstood the thread-safety guarantee?
Looks like a simple cut&paste error - you are joining to thread "w2" twice and never to "w1". At present, you would expect the thread "w1" to still be running half the time when you print the 'final' value.
I have been working on a below sample code:
public class GlobalStatic_Multithread extends Thread{
private static int threadcounter = 0;
public void run()
{
threadcounter++ ;
System.out.println(threadcounter);
}
public static void main(String[] args) {
for(int i =0 ; i < 3 ; i++)
{
new GlobalStatic_Multithread().start();
}
System.out.println(threadcounter + " main ending");
}
}
It is very clear three threads with each having it's own lock for the class GlobalStatic_Multithread will be started. My peers explanation for this program is, After Thread-1 starts the static variable threadcounter which is an int will be incremented to value 1. Before it get's printed there is every chance OS will preempts Thread-1 and runs Thread-2, it (Thread-2) will hold value 1 for threadcounter and it will increment to 2 and it gets printed (I mean Thread-2 will print) before Thread-1 prints value of threadcounter as 2. I am very clear on this theory and I clearly know the difference between static and non-static variables. There is some subtleness which I am not able to understand how these threads getting values for threadcounter. My contention here is when Thread-1 started, it has it own local cache, so it should only look at it's own local cache unless the threadcounter is marked as volatile. When OS preempts Thread-1 just before it prints the value and let Thread-2 to run, Thread-2 incremented threadcounter to 2. How the Thread-1 got the value of threadcounter as 2 ? and Shouldn't Threads fetch values from their own cache? . Because, when OS preempts Thread-1, it is holding value of threadcounter as 1 in it's own cache and it should print threadcounter as 1. I am missing something about JVM heap and threads local cache, hence I had to post this question. I know static member variables are associated with class and they have give constant value for all objects in a program (in other words if two objects of a class using static member variable int i=0 and one object increments to i++ then second object will get the updated value, which is 1 in this case). And I also knew the static member variables are stored in heap of JVM. And also I knew when JVM starts it loads each started thread with it's own copy of cache and that cache will hold all values of the class members.
Is it possible your coming from a different language and static means something different than what you're used to? Static in Java means there is only one property for the class, hence it is shared among the instances. Try running this to see if it makes more sense.
public class GlobalStatic_Multithread extends Thread{
private static int classCounter = 0;
private int instanceCounter = 0;
public void run()
{
++classCounter;
++instanceCounter;
System.out.println("classCounter:" + classCounter + " instanceCounter:" + instanceCounter);
}
public static void main(String[] args) {
for(int i =0 ; i < 3 ; i++)
{
new GlobalStatic_Multithread().start();
}
System.out.println(threadcounter + " main ending");
}
There is a lot of flexibility in optimization that could be done by compiler and also hotspot native compilation, and you should not depend on any behavior that is not spec'd for the language. If you are doing multithreaded programming, then you should program to get the express behavior you seek.
What you are doing right now is not threadsafe and will give undetermined results.
If you want increments to the static field to always take into consideration increments already made by both this and other threads, then you COULD use synchronization, but it would be better if you used one of the atomic classes:
public class GlobalStatic_Multithread extends Thread{
private static AtomicInteger threadcounter = new AtomicInteger(); // defaults to 0
public void run()
{
int incrementedValue = threadcounter.incrementAndGet() ;
System.out.println(incrementedValue);
}
public static void main(String[] args) {
for(int i =0 ; i < 3 ; i++)
{
new GlobalStatic_Multithread().start();
}
System.out.println(threadcounter.get() + " main ending");
}
Furthermore, if you want to know that the 3 threads have finished their work before you get the value to print from main, then you should do something like this:
public class GlobalStatic_Multithread extends Thread {
private static AtomicInteger threadcounter = new AtomicInteger(); // defaults to 0
private CountDownLatch doneSignal; // This will be passed to constructor instead of
// static, to avoid race condition on construction
// of object on main thread.
public GlobalStatic_Multithread(CountDownLatch doneSignal) {
this.doneSignal = doneSignal;
}
public void run()
{
int incrementedValue = threadcounter.incrementAndGet() ;
System.out.println(incrementedValue);
doneSignal.countDown();
}
public static void main(String[] args) {
int threadsToStart = 3;
CountDownLatch latch = new CountDownLatch(threadsToStart );
for(int i =0 ; i < threadsToStart ; i++)
{
new GlobalStatic_Multithread(latch).start();
}
latch.await(); // waits for all threads to finish (latch value goes to 0)
System.out.println(threadcounter.get() + " main ending");
}
I'm trying to implement a simple problem where i have a global variable to sell tickets.
I spawn 3 threads to sell 10 tickets and this i'm doing using a binary semaphore.
private static int noOfTickets =10;
private static boolean soldAll = false;
private static Random r = new Random(10);
/************ MAIN **************/
public static void main(String[] arg){
// spawn 10 threads to see a tickets
for(int i =0; i<3; i++){
Thread t = new Thread(new sellRunnable());
t.setName("Me_"+i);
t.start();
}
}
/************ MAIN **************/
public static void sell() throws InterruptedException{
Semaphore b = new Semaphore(1);
int numOfTicketsSoldByThisThread = 0;
while(!soldAll){
addRandomDelay(1000, 100);
b.acquire();
if(noOfTickets>0){
Thread t = Thread.currentThread();
numOfTicketsSoldByThisThread++;
noOfTickets--;
System.out.println("I "+t.getName()+" sold "+numOfTicketsSoldByThisThread+"ticket. tickets left are "+noOfTickets);
}else{
soldAll = true;
System.out.println(" sold all tickets");
}
b.release();
}// end of while
}
public static class sellRunnable implements Runnable{
public void run() {
try {
sell();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
When i run this code, i'm not getting the correct output, at some point of time
I get this
I Me_2 sold 1ticket. tickets left are 7
I Me_1 sold 1ticket. tickets left are 7
Notice, how two threads are printing out that the tickets left is 7?. That can't be right? I know that noOfTicketsLeft-- is NOT an atomic operation, but it's inside the semaphore. So,it should work?
You need to use the same Semaphore instance for all three threads. As it stands, they're all pointing to different semaphores, so they don't actually lock each other out.
BTW, even though this looks like it might just be for quick practice, you really should get out of the habit of using static variables; declare a class, and then instantiate it and invoke it in main(). It doesn't take much more effort, and it's far cleaner.
Because it always prints out '3'. No synchronization needed? I am testing this simple thing because I am having a trouble in a real multiple thread problem, which isn't good to illustrate the problem, because it's large. This is a simplified version to showcase the situation.
class Test {
public static int count = 0;
class CountThread extends Thread {
public void run()
{
count++;
}
}
public void add(){
CountThread a = new CountThread();
CountThread b = new CountThread();
CountThread c = new CountThread();
a.start();
b.start();
c.start();
try {
a.join();
b.join();
c.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) {
Test test = new Test();
System.out.println("START = " + Test.count);
test.add();
System.out.println("END: Account balance = " + Test.count);
}
Because it always prints out '3'. No synchronization needed?
It is not thread safe and you are just getting lucky. If you run this 1000 times, or on different architectures, you will see different output -- i.e. not 3.
I would suggest using AtomicInteger instead of a static field ++ which is not synchronized.
public static AtomicInteger count = new AtomicInteger();
...
public void run() {
count.incrementAndGet();
}
...
Seems to me like count++ is fast enough to finish until you invoke 'run' for the other class. So basically it runs sequential.
But, if this was a real life example, and two different threads were usingCountThread parallelly, then yes, you would have synchronization problem.
To verify that, you can try to print some test output before count++ and after, then you'll see if b.start() is invoking count++ before a.start() finished. Same for c.start().
Consider using AtomicInteger instead, which is way better than synchronizing when possible -
incrementAndGet
public final int incrementAndGet()
Atomically increments by one the current value.
This code is not thread-safe:
public static int count = 0;
class CountThread extends Thread {
public void run()
{
count++;
}
}
You can run this code a million times on one system and it might pass every time. This does not mean is it is thread-safe.
Consider a system where the value in count is copied to multiple processor caches. They all might be updated independently before something forces one of the caches to be copied back to main RAM. Consider that ++ is not an atomic operation. The order of reading and writing of count may cause data to be lost.
The correct way to implement this code (using Java 5 and above):
public static java.util.concurrent.atomic.AtomicInteger count =
new java.util.concurrent.atomic.AtomicInteger();
class CountThread extends Thread {
public void run()
{
count.incrementAndGet();
}
}
It's not thread safe just because the output is right. Creating a thread causes a lot of overhead on the OS side of things, and after that it's just to be expected that that single line of code will be done within a single timeslice. It's not thread safe by any means, just not enough potential conflicts to actually trigger one.
It is not thread safe.
It just happened to be way to short to have measurable chance to show the issue. Consider counting to much higher number (1000000?) in run to increase chance of 2 operations on multiple threads to overlap.
Also make sure your machine is not single core CPU...
To make the class threadsafe either make count volatile to force memory fences between threads, or use AtomicInteger, or rewrite like this (my preference):
class CountThread extends Thread {
private static final Object lock = new Object();
public void run()
{
synchronized(lock) {
count++;
}
}
}
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
public class Main implements Runnable {
private final CountDownLatch cdl1 = new CountDownLatch(NUM_THREADS);
private volatile int bar = 0;
private AtomicInteger count = new AtomicInteger(0);
private static final int NUM_THREADS = 25;
public static void main(String[] args) {
Main main = new Main();
for(int i = 0; i < NUM_THREADS; i++)
new Thread(main).start();
}
public void run() {
int i = count.incrementAndGet();
cdl1.countDown();
try {
cdl1.await();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
bar = i;
if(bar != i)
System.out.println("Bar not equal to i");
else
System.out.println("Bar equal to i");
}
}
Each Thread enters the run method and acquires a unique, thread confined, int variable i by getting a value from the AtomicInteger called count. Each Thread then awaits the CountDownLatch called cdl1 (when the last Thread reaches the latch, all Threads are released). When the latch is released each thread attempts to assign their confined i value to the shared, volatile, int called bar.
I would expect every Thread except one to print out "Bar not equal to i", but every Thread prints "Bar equal to i". Eh, wtf does volatile actually do if not this?
It is a deliberate intention that each Thread attempts to set the value of bar at exactly the same time.
EDIT:
In light of the answer, changed code to this:
...
bar = i;
try {
Thread.sleep(0);
} catch(InterruptedException e) {
e.printStackTrace();
}
...
To ensure that a little time is wasted between the set and read of the variable.
Now the print is 50/50 on same/different value for Bar.
The JVM decides when the threads run, not you. If it felt like holding one of the ones whose latch just released for another 10ms, just because, it can do that. After the latch releases, they still have to wait for their turn to execute. Unless you're running it on a 25 core computer, they're not all assigning bar at anywhere near 'the same time' down inside the machine. Since all you're doing is a couple of primitive operations, it's extremely unlikely that one of them won't finish inside its time slice before the next one gets released!
It's not. You're misusing it. There is a great article here by Herb Sutter that explains it in more detail.
The basic idea is that volatile makes variables unoptimisable. It does not make them thread safe.
To answer the 'WTF does volatile actually do?':
volatile is all about visibility. In Java's thread model, if a thread A writes into a regular shared field, there is no guarantee that a thread B will ever see the value written by A, unless the threads are synchronized somehow. volatile is one of the synchronization mechanisms.
Unlike non-volatile fields, when thread A writes into a volatile field and thread B later reads it, B is guaranteed to see the new value and not an older version.
(Actually volatile does even more - thread B will not only see the new value of the field, but everything else written by A before it set the volatile variable as well. It established a happened-before relationship).
What you should do is replace your instance of volatile int with AtomicInteger. See here.
I think you meant to write this:
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
public class Main implements Runnable {
private final CountDownLatch cdl1 = new CountDownLatch(NUM_THREADS);
private volatile int bar = 0;
private AtomicInteger count = new AtomicInteger(0);
private static final int NUM_THREADS = 25;
public static void main(String[] args) {
Main main = new Main();
for(int i = 0; i < NUM_THREADS; i++)
new Thread(main).start();
}
public void run() {
int i = count.incrementAndGet();
bar = i;
cdl1.countDown();
try {
cdl1.await();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
if(bar != i)
System.out.println("Bar not equal to i");
else
System.out.println("Bar equal to i");
}
}
Which prints "Bar not equal to i" like you expected.