Reputation: 525
Let's say we have 2 threads, and one object with 2 methods. Thread 1 uses method1. While method1 used by thread 1 is still running, can thread 2 use method2?
All of this assuming the object was not built with multithreading in mind (no synchronize or similar), and the methods do not access the same variables.
this code suggests that it is possible:
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class multithreadaccess {
/**
* @param args
* the command line arguments
*/
public static void main(String[] args) throws IOException {
TestClass tc = new TestClass();
// invokes not sync method
FirstThreadRunnable ftr = new FirstThreadRunnable(tc);
Thread t1 = new Thread(ftr);
// invokes the sync method
SecondThreadRunnable str = new SecondThreadRunnable(tc);
Thread t2 = new Thread(str);
t1.start();
t2.start();
System.in.read();
}
public static class TestClass {
private int callCount = 0;
public void secondmethod() {
System.out.println("second method activated! Call number:" + " [" + callCount++ + "] from thread: "
+ Thread.currentThread().getId());
}
public void firstmethod() throws InterruptedException {
// Test with the sleep
System.out.println("starting first slow method from thread: " + Thread.currentThread().getId());
Thread.sleep(1000); // hold the monitor for 5sec
System.out.println("stopping first slow method! Call number:" + " [" + callCount++ + "] from thread: "
+ Thread.currentThread().getId());
// Test with spinning
/*
* System.out.println("MAKE IT SPIN! from thread: " +
* Thread.currentThread().getId()); boolean spin = true;
* while(spin){
*
* } System.out.println("IT STOPPED SPINNING! from thread: " +
* Thread.currentThread().getId()); }
*/
}
}
// invokes the not sync method
public static class FirstThreadRunnable implements Runnable {
TestClass tester = null;
public FirstThreadRunnable(TestClass tester) {
this.tester = tester;
}
@Override
public void run() {
try {
tester.firstmethod();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
// invokes the sync method
public static class SecondThreadRunnable implements Runnable {
TestClass tester = null;
public SecondThreadRunnable(TestClass tester) {
this.tester = tester;
}
@Override
public void run() {
tester.secondmethod();
}
}
}
modified code from here
I do not understand how this is possible, though. I was always thinking an object is linear code. But this suggests that linear is only the code within the methods(As long as no variables are used by multiple methods)?
Upvotes: 0
Views: 117
Reputation: 6309
The problem of your code is the 2 methods firstmethod
and secondmethod
are not as "independent" as you thought, because both have callCount++
.
This may create race condition, because both thread are updating that variable. You need to use AtomicInteger
instead of int, then the code will work.
Edit:
In general, synchronization mechanism ("automatic blocking") is not enabled by default, because these operations are expensive and slow down the program. That's why Java provides synchronized
keyword as well as threadsafe classes such has AtomicInteger
to ensure proper access to shared variables and critical sections.
Upvotes: 4