I am kinda new to threads. How can I prove, by writing code in a separate class, that MyClass class isn't thread safe? I've been searching but I can't really find an example to aid me.
public class MyClass {
private static int value = 0;
public static void set(int setVal) {
value = setVal;
}
public static int get() {
return value;
}
public static void decrement() {
int temp = value;
value = --temp;
}
}
public static void main(String[] args) {
int nt = 10;
int c = 20000;
MyClass.set(c);
Thread[] threads = new Thread[nt];
for (int t = 0; t < nt; t++) {
Thread thread = new Thread(() -> {
for (int i = 0; i < c; i += nt) {
MyClass.decrement();
}
});
thread.start();
threads[t] = thread;
}
try {
for (Thread thread : threads) {
thread.join();
}
} catch (Throwable tr) {
tr.printStackTrace();
}
System.out.println(MyClass.get());
}
Try this. If you add synchronized to the decrement method of MyClass it will print out 0 (thread safe), but if you don't synchronize decrement than it will print out a wrong number.
This proves that MyClass (its decrement method) is not thread prove, since if it was it would print out 0.
Also, if you can't use lambdas than replace the first for loop with the following:
for (int t = 0; t < nt; t++) {
Thread thread = new Thread(() -> {
for (int i = 0; i < c; i += nt) {
MyClass.decrement();
}
});
thread.start();
threads[t] = thread;
}
Hope I could help!
Related
This is the program
public class Thread2 implements Runnable {
private static int runTill = 10000;
private static int count = 0;
#Override
public void run() {
for(int i=0;i<runTill;i++) {
count++;
}
}
public static void main(String s[]) {
int iteration = 10;
for(int i = 0; i < iteration ;i++) {
Thread t = new Thread(new Thread2());
t.start();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Expected : "+(iteration * runTill));
System.out.println("Actual : "+count);
}
}
At the end I want count to be equal to (Expected : 100000). How can I achieve this?
A call to count++ is not atomic: it first has to load count, increment it and then store the new value in the variable. Without synchronization in place, threads will interleave during execution of this operation.
A simple way to get what you want is to use an AtomicInteger:
private static AtomicInteger count = new AtomicInteger();
#Override
public void run() {
for(int i=0;i<runTill;i++) {
count.incrementAndGet();
}
}
use "compare and set" instead of "increment and get"
private static AtomicInteger count = new AtomicInteger();
#Override
public void run() {
for(int i=0;i<runTill;i++) {
//note: another thread might reach this point at the same time when i is 9,999
// (especially if you have other codes running prior to the increment within the for loop)
// then count will be added 2x if you use incrementAndGet
boolean isSuccessful = count.compareAndSet(i, i+1);
if(!isSuccessful)
System.out.println("number is not increased (another thread already updated i)");
}
}
As the comments suggest, besides the need for synchronizing access (to count, became an AtomicInteger here), threads should be waited to complete using Thread.join(), instead of "guessing" their runtime:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class Thread2 implements Runnable {
private static int runTill = 10000;
private static AtomicInteger count = new AtomicInteger();
#Override
public void run() {
for (int i = 0; i < runTill; i++) {
count.incrementAndGet();
}
}
public static void main(String s[]) {
int iteration = 10;
List<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < iteration; i++) {
Thread t = new Thread(new Thread2());
threads.add(t);
t.start();
}
try {
for (Thread t : threads)
t.join();
} catch (InterruptedException ie) {
ie.printStackTrace();
}
System.out.println("Expected : " + (iteration * runTill));
System.out.println("Actual : " + count);
}
}
I have a class variable, sum. Every time I start a new thread, I want the sum to increment. It seems that run is only being called once, and I can't find better info to tell me more about it. Is there a way I could accomplish this with locks? Here is some simple code:
public class MyClass implements Runnable{
static int sum = 0;
public static void main(String[] args) throws InterruptedException {
for(int i = 0; i < 5; ++i){
Thread t = new Thread(new MyClass());
t.start();
t = null;
}
}
#Override
public synchronized void run() {
++sum;
System.out.println(sum);
}
}
Keeping mutable state in static variables is a bad practice, but this is how you would fix this to work:
public class MyClass implements Runnable {
static AtomicInteger counter = new AtomicInteger(0);
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 5; ++i) {
Thread t = new Thread(new MyClass());
t.start();
t = null;
}
}
#Override
public void run() {
int sum = counter.incrementAndGet();
System.out.println(sum);
}
}
Since sum is instance variable, for instance of MyClass there is a variable sum with initial value as 0. Mark the Sum as static to use it at class level.
public class MyClass implements Runnable{
static int sum = 0;
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 5; ++i) {
Thread t = new Thread(new MyClass());
t.start();
t = null;
}
}
public void run() {
synchronized (this) {
sum++;
System.out.println(sum);
}
}
}
This is the output:
1
2
3
4
5
I have a following code as below:
class Example {
private volatile int testValue = 0;
public int getTestValue() {
return testValue;
}
public void setTestValue(int testValue) {
this.testValue = testValue;
}
public void increment() {
this.testValue += 1;
}
}
class PrintThread extends Thread {
private Example example;
private int x = 0;
public PrintThread(Example example) {
this.example = example;
x = example.getTestValue();
}
public void run() {
while(true) {
if(x != example.getTestValue()) { // block 1
System.out.println("printThread: " + example.getTestValue());
x = example.getTestValue();
}
}
}
}
class IncrementorThread extends Thread {
private Example example;
public IncrementorThread(Example example) {
this.example = example;
}
public void run() {
while(true) {
example.increment();
System.out.println("incrementorThread: " + example.getTestValue());
try {
Thread.sleep(800);
} catch(Exception ex) {
}
}
}
}
public class VolatileExample {
public static void main(String args[]) {
Example ex = new Example();
new IncrementorThread(ex).start();
new PrintThread(ex).start();
}
}
When I remove volatile keyword in Example class then I never see the output of PrintThread. In PrintThread when I print out the testValue of example, value of example object still updated but the code in 'block 1' never be executed. Both thread still access the same object, can anyone explain me more detail about this? About the volatile keyword affected in this case
You should use atomic integers insteed of volatile fields. To get the idea why that is important try running code below. Here you have 3 types of variables, normal int, volatile int and AtomicInteger. Only AtomicInteger assure the thread safety of value. After running this simple code, you will see why.
public class Test {
private int threadCount = 10;
private int nonVolatileCount = 0;
private volatile int volatileCount = 0;
private AtomicInteger atomicCount = new AtomicInteger(0);
private CountDownLatch startLatch = new CountDownLatch(threadCount);
private CountDownLatch endLatch = new CountDownLatch(threadCount);
private class Task implements Runnable {
public void run() {
startLatch.countDown();
try {
startLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 1000000; i++) {
nonVolatileCount++;
volatileCount++;
atomicCount.incrementAndGet();
}
endLatch.countDown();
};
}
public static void main(String[] args) throws InterruptedException {
new Test().go();
}
public void go() throws InterruptedException {
for (int i = 0; i < threadCount; i++) {
new Thread(new Task()).start();
}
endLatch.await();
System.out.println("non volatile counter: " + nonVolatileCount);
System.out.println(" volatile counter: " + volatileCount);
System.out.println(" atomic counter: " + atomicCount.get());
}
}
I am trying to write Thread Interference Example.
Below is my code:
class Counter {
private int c = 0;
public void increment() {
c++;
}
public void decrement() {
c--;
}
public int value() {
return c;
}
}
Suppose Thread A invokes increment at about the same time Thread B invokes decrement.
How to implement this one.
There is not guarantee how they will run it depends on OS scheduler. There is nothing better than this
Thread a = new ThreadA();
Thread b = new ThreadB();
a.start();
b.start();
To get two threads to start executing at the same time you can use a latch. (Which is to say, two threads that become available for execution as close together as possible.) Still for a single increment/decrement each it will probably take many runs to observe an interference. For a repeatable experiment you probably want to call increment/decrement several times in parallel and observe the final value of c.
final Counter counter = new Counter()
final CountDownLatch latch = new CountDownLatch(1);
Thread thread1 = new Thread(new Runnable() {
public void run() {
latch.await();
for (int i = 0; i < 100; i++) {
counter.increment();
}
}}).start():
Thread thread2 = new Thread(new Runnable() {
public void run() {
latch.await();
for (int i = 0; i < 100; i++) {
counter.decrement();
}
}}).start():
Thread.sleep(10);//give thread 2 a timeslice to hit the await
latch.countDown();
System.out.println(counter.value()); //non-zero value indicates interference
Now in this example if you try to execute and the output false shows interference.
How it works:
Both the Runnables keep a thread local count which is incremented for each invocation of increment() and decrement(). So after execution for some amount of time if we try to validate the values
Then you can say that:
value of Counter = invocation of increment() - invocation of decrement().
But when you try to verify this at the end of execution you get false. Which shows that the actual counter value was not as expected.
public static void main(String[] args) throws InterruptedException
{
Counter c = new Counter();
IncrementingRunnable incRunnable = new IncrementingRunnable(c);
DecrementingRunnable decRunnable = new DecrementingRunnable(c);
Thread tA = new Thread(incRunnable);
Thread tB = new Thread(decRunnable);
tA.start();tB.start();
Thread.sleep(10000);
stop = true;
tA.join();
tB.join();
//verify value
int actualCount = c.c;
int expectedCount = incRunnable.count - decRunnable.count;
System.out.println(actualCount == expectedCount);
}
public static volatile boolean stop = false;
static class IncrementingRunnable implements Runnable{
volatile int count = 0;
private Counter counter;
public IncrementingRunnable(Counter c) {
this.counter = c;
}
#Override
public void run() {
while(!stop){
counter.increment();
count++;
}
}
}
static class DecrementingRunnable implements Runnable{
volatile int count = 0;
private Counter counter;
public DecrementingRunnable(Counter c) {
this.counter = c;
}
#Override
public void run() {
while(!stop){
counter.decrement();
count++;
}
}
}
Now try changing the primitive c in Counter to AtomicInteger and see the output again. You will find that now the output is true.
Okay so I am having trouble with this maybe i have just been thinking too long or am dumb but here is what i have and what i am trying to do:
Update- code all fixed no more run problems.
public class myClass program {
int [] w = null;
int [] x = null;
Thread T = null;
public static void main(String [] args){
x = new int[5];
w = new int[5];
// here i am trying to invoke a new thread passing the index
// of my array, then incrementing the index each time i create a new thread
// the purpose is to fill each index each time the new thread runs.
for(int i = 0; i < w.length; i ++){
// T = new Thread(new myThreadClass(w[i])); // only passes 0 take this out and
T = new Thread( new myThreadClass(i)); // pass i so the position changes
T.start();
try{
Thread.sleep(100);
}catch(Exception e){}
}
}
in my separate class myThreadClass.java i have the following:
public class myThreadClass extends Thread{
int [] w = null;
int position = 0;
int value = 1;
public myThreadClass(int p){
this.position = p
w = myClass.w;
}
#Override
public void run(){
// synchronize the thread so there is no memory cache problems
//
synchronized(w){
w[position] = value;
}
}
}
when i print out the output of w from myClass:
i get w = 1 0 0 0 0
but i want w = 1 1 1 1 1
EDITED- i am now getting the right output - check the code for changes
In this part myThreadClass(w[i]) you are not passing an index, you are passing a value, which is zero because w is an array of 5 elements, all of them initialized with the default value of 0.
You should do myThreadClass(i) instead.
w[] is initially all ZERO. you are passing one of these values to the thread constructor
This line from myClass:
w = new int[5];
initializes all the elements of w to 0.
so, when you call
T = new Thread( new myThreadClass(w[i]));
your are effectively doing this:
T = new Thread( new myThreadClass(0));
so the only element of w[] that will ever change is the first one.
Here's an over-engineered solution for your problem. You could do just fine without encapsulation, but I decided to use it because it makes the example more readable.
public class Test {
public static void main(String[] args) {
// Create the resultset containing the result
ResultSet resultSet = new ResultSet(5);
Thread[] threads = new Thread[resultSet.getSize()];
// Create threads
for (int i = 0; i < resultSet.getSize(); i++) {
threads[i] = new Thread(new TestTask(
resultSet.createResultSetter(i)));
}
// Start threads
for (int i = 0; i < resultSet.getSize(); i++) {
threads[i].start();
}
// Wait until threads complete
for (int i = 0; i < resultSet.getSize(); i++) {
try {
threads[i].join();
} catch (InterruptedException exception) {
// ??!
}
}
// Print the result
for (int i = 0; i < resultSet.getSize(); i++) {
System.out.println(resultSet.getResult(i));
}
}
/**
* Interface used to set the result
*/
public static interface ResultSetter {
public void setResult(int result);
}
/**
* Container class for results
*/
public static class ResultSet {
private final int[] results;
public ResultSet(int size) {
results = new int[size];
}
public int getSize() {
return results.length;
}
public ResultSetter createResultSetter(final int position) {
return new ResultSetter() {
public void setResult(int result) {
ResultSet.this.setResult(position, result);
}
};
}
public synchronized int getResult(int position) {
return results[position];
}
public synchronized void setResult(int position, int result) {
results[position] = result;
}
}
/**
* A task executed by a thread
*/
public static class TestTask implements Runnable {
private ResultSetter resultSetter;
public TestTask(ResultSetter resultSetter) {
this.resultSetter = resultSetter;
}
#Override
public void run() {
resultSetter.setResult(1);
}
}
}