一、数据类型String的常量池特性
在JVM中具有String常量池缓存功能。将Synchronized(string)和String联合使用时,需要注意常量池带来的一些例外。当string的值都相等时,表明两个线程持有的是相同的锁,其中一个线程不停下来,另一个线程将永远不能被执行。因此大多数情况下,synchronized代码块不使用String作为锁对象,而改用其他,比如new Object实例化一个Object对象。
二、同步synchronized方法容易造成死锁,可以用同步块来解决这样的问题。
三、多线程的死锁
不同的线程都在等待根本不可能被释放得锁,从而导致所有任务都无法继续完成。只要互相等待对方释放锁就有可能出现死锁。
DealThread.java
/*
* 互相等待对方释放锁就有可能出现死锁。
*/
public class DealThread implements Runnable{
public String username;
public Object lock1=new Object();
public Object lock2=new Object();
public void setFlag(String username){
this.username=username;
}
@Override
public void run() {
if(username.equals("aa")){
synchronized (lock1) {
try{
System.out.println("username="+username);
Thread.sleep(3000);
}catch(InterruptedException e){
e.printStackTrace();
}
synchronized (lock2) {
System.out.println("按照locak1->locak2代码顺序执行");
}
}
}
if(username.equals("bb")){
synchronized (lock2) {
try{
System.out.println("usernmae="+username);
Thread.sleep(3000);
}catch(InterruptedException e){
e.printStackTrace();
}
synchronized (lock1) {
System.out.println("按照lock2->locak1代码顺序执行");
}
}
}
}
}
Run.java
public class Run {
public static void main(String[] args) {
try{
DealThread t1=new DealThread();
t1.setFlag("aa");
Thread thread1=new Thread(t1);
thread1.start();
Thread.sleep(100);
t1.setFlag("bb");
Thread thread2=new Thread(t1);
thread2.start();
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
结果如下:
原因就是两个线程都在互相等待对方释放锁。