多线程-同步代码块中的隐患及解决办法
多线程访问同步代码块出现阻塞并解决
/**
* 多线程访问同步代码块出现阻塞并解决
* 锁代码块:作用的对象时整个代码块、每个对象只有一个锁与之关联
* 阻塞原因:synchronized会将当前对象锁住,只有执行完才会释放该对象锁,下一个线程才能得到锁,从而形成互斥性
*/
public class SynchronizedCodeQuick {
public static void main(String[] args) {
//多线程访问会阻塞 原因没释放锁,一个对象一个锁形成互斥性
// MyThread myThread = new MyThread();
// Thread thread1 = new Thread(myThread, "thread1");
// Thread thread2 = new Thread(myThread, "thread2");
// thread1.start();
// thread2.start();
//多线程访问不会阻塞 两把锁互不干扰、没有互斥性
Thread thread1 = new Thread(new MyThread(),"thread1");
Thread thread2 = new Thread(new MyThread(),"thread2");
thread1.start();
thread2.start();
}
}
class MyThread implements Runnable {
@Override
public void run() {
synchronized (this) {
for (int i = 0; i < 5; i++) {
System.out.println("线程名:" + Thread.currentThread().getName() + ":" + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
注释的代码运行如下:
优化后的效果
多线程访问synchronized和非synchronized
/**
* 多线程访问synchronized和非synchronized 并不阻塞,证实了synchronized作用范围就是被修饰的代码块
*/
public class IsBlockSynchronizedCodeQuick {
public static void main(String[] args) {
MyIsThread myThread = new MyIsThread();
Thread thread1 = new Thread(myThread, "thread1");
Thread thread2 = new Thread(myThread, "thread2");
thread1.start();
thread2.start();
}
}
class MyIsThread implements Runnable {
public void test1() {
synchronized (this) {
for (int i = 0; i < 5; i++) {
System.out.println("线程名" + Thread.currentThread().getName() + ":" + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void test2() {
for (int i = 0; i < 5; i++) {
System.out.println("线程名" + Thread.currentThread().getName() + ":" + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public void run() {
String name = Thread.currentThread().getName();
if("thread1".equals(name)){
test1();
}else {
test2();
}
}
}
总结: