朋友最近问我一个多线程的问题,
1.当一个类有两个方法(A和B)都用syncronized修饰,那么多线程访问会是怎么样?
2.当一个类有两个方法(A和B)都用static syncronized修饰,那么多线程访问会怎样?
问题2当然是锁的实例的Class对象,多线程访问会同步访问,同一时间只有一个线程执行一个方法(A或者B)
现在就演示下问题1的答案:
(1)一个实例,多线程分别访问这个实例的非静态加锁方法A和B,线程池1执行方法A时,线程池2执行B的线程会被阻塞
public class ThreadTest {
public synchronized void getA(){
System.out.println("getA()方法打印,线程===="+Thread.currentThread().getName());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void getB(){
System.out.println("getB()方法打印,线程===="+Thread.currentThread().getName());
}
public static void main(String[] args) {
ExecutorService executor1 = Executors.newFixedThreadPool(10);
ExecutorService executor2 = Executors.newFixedThreadPool(10);
ThreadTest threadTest1 = new ThreadTest();
for(int i = 0;i<2;i++){
executor1.submit(() -> threadTest1.getA());
executor2.submit(() -> threadTest1.getB());
}
executor1.shutdown();
executor2.shutdown();
}
}
(2)两个实例,多线程分别访问这个实例的非静态加锁方法A和B,线程池1执行方法A时,线程池2执行B的线程不会被阻塞
public class ThreadTest {
public synchronized void getA(){
System.out.println("getA()方法打印,线程===="+Thread.currentThread().getName());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void getB(){
System.out.println("getB()方法打印,线程===="+Thread.currentThread().getName());
}
public static void main(String[] args) {
ExecutorService executor1 = Executors.newFixedThreadPool(10);
ExecutorService executor2 = Executors.newFixedThreadPool(10);
ThreadTest threadTest1 = new ThreadTest();
ThreadTest threadTest2 = new ThreadTest();
for(int i = 0;i<2;i++){
executor1.submit(() -> threadTest1.getA());
executor2.submit(() -> threadTest2.getB());
}
executor1.shutdown();
executor2.shutdown();
}
}
(3)不论多少个实例,多线程分别访问这个实例的静态加锁方法A和B,线程池1执行方法A时,线程池2执行B的线程都会被阻塞
public class ThreadTest {
public static synchronized void getA(){
System.out.println("getA()方法打印,线程===="+Thread.currentThread().getName());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static synchronized void getB(){
System.out.println("getB()方法打印,线程===="+Thread.currentThread().getName());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ExecutorService executor1 = Executors.newFixedThreadPool(10);
ExecutorService executor2 = Executors.newFixedThreadPool(10);
for(int i = 0;i<2;i++){
executor1.submit(() -> getA());
executor2.submit(() -> getB());
}
executor1.shutdown();
executor2.shutdown();
}
}