麻烦大家看一下下边的程序片断的输出为什么是in thread 2 maple
in thread 1 maple我在两个线程里都用sychronized把a锁掉了阿,为什么会出现并发访问的问题,难道sleep()会释放对象锁??
public class ThreadTest {    static String a = "";    public static void main(String[] args) {        Thread thread1 = new Thread() {            public void run() {                synchronized (a) {                    a = "lincoln";                    try {                        Thread.sleep(500);                    } catch (InterruptedException e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                    }                    System.out.println("in thread 1 " + a);
                }            }        };        Thread thread2 = new Thread() {        public void run() {                synchronized (a) {                    a = "maple";                    try {                        Thread.sleep(100);                    } catch (InterruptedException e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                    }                    System.out.println("in thread 2 " + a);                }            }        };        thread1.start();        thread2.start();    }}

解决方案 »

  1.   

    你通过 线程 1 里面线程1的锁对象是 “”;
    但是  a = "lincoln"; 这一句后
    线程2的锁对象成了 lincoln 这两个线程 不是公用一个锁 所以出现以上情况你可以把两个同步语句 改成这样 就可以得到你要的结果了 synchronized("")
      

  2.   

    造成这个现象的原因是String 的 特殊性 如果换成别的 对象为锁 就不会有问题了
      

  3.   

    第一个线程拿到的锁是 a = ""
    拿到后 把 a = "lincoln"
    于是第二个线程拿到的锁是 "lincoln"
    不是一个锁,所以两个线程并没互斥
      

  4.   

    To: interpb,谢谢回复不过好像不行,我代码改成这样了结果还是一样的synchronized应该是锁对象的引用阿,和值有关系么?public class ThreadTest {    static String a = "";
        static String b = "";    public static void main(String[] args) {
        
            Thread thread1 = new Thread() {
                
                public void run() {                synchronized (b) {                    a = "lincoln";
                        
                        try {
                            Thread.sleep(500);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }                    System.out.println("in thread 1 " + a);               
                    }
                }
            };        Thread thread2 = new Thread() {
                
             public void run() {                synchronized (b) {
                        
                        a = "maple";
                   
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }                    System.out.println("in thread 2 " + a);
                    }            }
            };        thread1.start();        thread2.start();
        }}
      

  5.   

    synchronized ("") 
     synchronized ("")是这样锁 肯定是 值 不是引用
      

  6.   

    看错 你这样 是一样的呵呵in thread 1 lincoln
    in thread 2 maple
      

  7.   

    to interpb:不好意思,我按你说的改了还是不行。。结果和原来一样,我还试着把锁的对象换成别的Object,也不可以
      

  8.   

    to interpb可不可以把你改的代码完整贴一下 谢谢!
      

  9.   

    啊 你是不是双核 处理器啊 呵呵不然怎么会这样 呵呵开个玩笑
    我这里运行的结果是in thread 1 lincoln
    in thread 2 maple是不是你要的结果
      

  10.   

    和你的一摸一样啊public class ThreadTest { static String a = ""; public static void main(String[] args) { Thread thread1 = new Thread() { public void run() { synchronized ("") { a = "lincoln"; try {
    Thread.sleep(500);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } System.out.println("in thread 1 " + a); }
    }
    }; Thread thread2 = new Thread() { public void run() { synchronized ("") { a = "maple"; try {
    Thread.sleep(100);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } System.out.println("in thread 2 " + a);
    } }
    }; thread1.start(); thread2.start(); }}
      

  11.   

    奇怪,我这边的输出还是一样的。。难道是我JVM的问题。。明白你的意思了,谢谢!我结贴了