public class TestSynchronized{
public static void main(String args[]){
  TestThread t = new TestThread();
  new Thread(t).start();
  new Thread(t).start();
  new Thread(t).start();
}
}class TestThread implements Runnable{
  int num = 100;
  String str = new String();
  public void run(){
     synchronized(str){
                             //锁str对象什么意思?
     while(true){
        if(num>0){
           try{
              Thread.sleep(10);
           }catch(Exception e){
              e.getMessage();
           }
           System.out.println(Thread.currentThread().getName()+"this is"+num--);
        }else{
           System.out.println("over");           
           break;
        }
     }
  }
  }
}rt,不明白,和synchronized(this)的效果一样的?

解决方案 »

  1.   

    资源同一时刻只能有一个进程或线程访问(Java中线程)在你的这个使用环境中synchronized(this) 不一样
      

  2.   

     synchronized(str)是Lock住TestThread中的String,也就是说如果有其他线程还是能够正常操作TestThread实例中的num等其他实例变量的,当然指的是用TestThread实例中的方法来操作实例中的其他实例变量。但是如果你用synchronized(this)就是Lock住TestThread实例,其他线程就无法操作TestThread实例了,也就是无法通过TestThread实例的方法操作其中的实例变量了。
      

  3.   

     String str =“hello";
    这样再试试。
      

  4.   

    this就是指当前对象,synchronized(this)就是锁住当前对象啊!str不就是当前对象吗?
      

  5.   

    synchronized的关键是锁住内存中的某一个类型所占用的内存区域,如果几个线程分别锁住了不同的区域,那当然互不干扰。但是如果锁住了同一个内存区域,线程之间就会串行化访问那块内存区域,也就是不会有多个线程同时访问那块内存区域。
    synchronized是否达到你要的效果,你就检查看看是否多个线程需要锁定的内存区域都是同一个内存区域,相当于就是多个引用是否都指向同一个实例。
      

  6.   

    锁str对象干什么?好像应该没什么影响?
    synchronized(str){}但结果又不一样了,为啥?
      

  7.   

    锁str对象干什么?好像应该没什么影响?
    去掉synchronized(str){}但结果又不一样了,为啥?
      

  8.   

    你的线程共享一个TestThread t = new TestThread();实例,所在str在你的这个程序里效果等同于锁住this,锁住就是为了做线程同步呀,线程一个一个访问TestThread的run方法。你看你的程序从头到尾就一个线程占用了TestThread。
      

  9.   

    public class TestSynchronized{
            public static void main(String args[]){
                  TestThread t = new TestThread();
                  new Thread(t).start();
                  new Thread(t).start();
                  new Thread(t).start();
            }
    }class TestThread implements Runnable{
          int num = 100;
          String str = new String();
          public void run(){
                synchronized(str){
                                 //锁str对象什么意思?
    int runTime = 0;
                        while(runTime < 100){
    runTime++;
    //                          if(num>0){
                                    try{
                                          Thread.sleep(10);
                                    }catch(Exception e){
                                          e.getMessage();
                                    }
                                    System.out.println(Thread.currentThread().getName()+"this is"+num--);
     //                         }else{    
     //                               System.out.println("over");                    
     //                               break;
     //                         }
                        }
                  }
          }
    }这样改一下就是每个线程运行100次循环。在这个例子里锁住str相当于锁住this。锁住了就能线程同步了呀,每个线程循序访问num。
    但是如果该为
    public class TestSynchronized{
            public static void main(String args[]){
                  TestThread t = new TestThread();
                  new Thread(t).start();
                  new Thread(t).start();
                  new Thread(t).start();
            }
    }class TestThread implements Runnable{
          int num = 100;
          String str = new String();
          public void run(){
    str = new String(); //这样就达不到锁住this的效果了。
                synchronized(str){
                                 //锁str对象什么意思?
    int runTime = 0;
                        while(runTime < 100){
    runTime++;
    //                          if(num>0){
                                    try{
                                          Thread.sleep(10);
                                    }catch(Exception e){
                                          e.getMessage();
                                    }
                                    System.out.println(Thread.currentThread().getName()+"this is"+num--);
     //                         }else{    
     //                               System.out.println("over");                    
     //                               break;
     //                         }
                        }
                  }
          }
    }
    就达不到锁住this的效果了,因为这个时候str指向的实例已经不是同一个了。
      

  10.   

    对不起啊,我真的没明白,this就是TestThread的实例,锁住str为什么就相当于锁住了this?
      

  11.   

    因为你只有一个run方法。run方法锁住了str,其他线程进入run之后要检查str是否被锁住,一看被锁住就停在那了。这就相当于锁住了this。
    public class TestSynchronized{
            public static void main(String args[]){
                  TestThread t = new TestThread();
                  new Thread(t).start();
                  new Thread(t).start();
                  new Thread(t).start();
      while(true)
      {
                                    try{
                                          Thread.sleep(1000);
                                    }catch(Exception e){
                                          e.getMessage();
                                    }
    t.printNum();
      }
            }
    }class TestThread implements Runnable{
          int num = 100;
          String str = new String();
          public void run(){
                synchronized(str){
    // synchronized(this){
                                 //锁str对象什么意思?
                        while(true){
                              if(num>0){
                                    try{
                                          Thread.sleep(100);
                                    }catch(Exception e){
                                          e.getMessage();
                                    }
                                    System.out.println(Thread.currentThread().getName()+"this is"+num--);
                              }else{    
                                    System.out.println("over");                    
                                    break;
                              }
                        }
                  }
          }
      
      synchronized public void printNum()
      {
    System.out.println(Thread.currentThread().getName()+" this is "+num);
      }
    }
    看看            synchronized(str){
    // synchronized(this){
    注释一个,换着看看效果是不是不一样了。如果把TestThread锁掉,那synchronized public void printNum()就不能访问了。如果只是锁掉str,那synchronized public void printNum()还是能访问的。
      

  12.   

    1.  把synchronized当作函数修饰符时,示例代码如下: 
    Public synchronized void method(){ 
    //…. 

    这也就是同步方法,那这时synchronized锁定的是哪个对象呢?他锁定的是调用这个同步方法对象。也就是说,当一个对象P1在不同的线程中执行这个同步方法时,他们之间会形成互斥,达到同步的效果。但是这个对象所属的Class所产生的另一对象P2却能够任意调用这个被加了synchronized关键字的方法。 
    上边的示例代码等同于如下代码: 
    public void method() 

    synchronized (this)      //  (1) 

           //….. 


    (1)处的this指的是什么呢?他指的就是调用这个方法的对象,如P1。可见同步方法实质是将synchronized作用于object reference。――那个拿到了P1对象锁的线程,才能够调用P1的同步方法,而对P2而言,P1这个锁和他毫不相干,程式也可能在这种情形下摆脱同步机制的控制,造成数据混乱:( 
    2.同步块,示例代码如下: 
    public void method(SomeObject so) { 
    synchronized(so) 

           //….. 


    这时,锁就是so这个对象,谁拿到这个锁谁就能够运行他所控制的那段代码。当有一个明确的对象作为锁时,就能够这样写程式,但当没有明确的对象作为锁,只是想让一段代码同步时,能够创建一个特别的instance变量(他得是个对象)来充当锁: 
    class Foo implements Runnable 

           private byte[] lock = new byte[0];  // 特别的instance变量 
        Public void method() 

           synchronized(lock) { //… } 

    //….. 

    注:零长度的byte数组对象创建起来将比任何对象都经济――查看编译后的字节码:生成零长度的byte[]对象只需3条操作码,而Object lock = new Object()则需要7行操作码。 摘自http://leo-faith.javaeye.com/blog/177779
      

  13.   

    对于多线程,理解的比较粗糙。仅限于现在够用。我的认识也许能帮 LZ 解决现在的问题。但是我想....前方的路很长。今天总是要比昨天更清晰。明天会更好.. 呵呵。一起加油吧。。1:java 对于多线程同步所涉及的最重要的概念就是“锁”。
    2:对于“锁”我的理解是:任意一个 java 对象都在其内部维持着一个“唯一的锁”,以实现多线程控制。可以粗糙的认为,每一个对象(无论是同一类型,还是不同类型的对象)都是独立的一把锁。
    3:锁的作用:锁住一个域(这个域可以是方法,也可以是一个代码段),使得该域每次只能有一个“使用该锁的线程”访问。
    4:锁的使用:需要配合 synchronized 关键字来使用。
       第一种情况,通过 synchronized 和一把锁实现多线程对一个“非方法域”的串行访问。例如:private Object lock;
    public  void operating() {
    synchronized(lock){
    //....
    }
    }   第二中情况,实现多线程对一个方法的串行访问.例如:public synchronized void operating() {
    //....
    }  当使用 synchronized 控制多线程对一个方法的串行访问时,实际上使用的是当前对象(即调用该方法的对象)做为锁。
      当你使用 synchronized 修饰了一个域时,肯定要有一个锁与其配套使用,如果你没显示的指定锁,那么就是使用当前对象作为锁(例如对方法使用 synchronized)。
    5:对于初学者(例如《原来的我》)有一个弯要转过来:不同的对象就是不同的锁。在多线程访问 synchronized 域时,只有所有线程使用的是同一把锁,才能实现串行访问,即同步。
    例如://这个写法相当弱,如果不是反面教材,我想没人会这么写。但我在初学时却总犯类似的错误。当然犯错时也不是写成这样,而是从外部传递了不同的锁。所以自己总结出这个写法,以警戒。
    synchronized(new Object()){ 

    }这段代码显然是不能实现同步的,各个线程使用的锁都不一样。
    对于另一些初学者(例如 LZ)又要有一个弯要转过来:只要所有线程使用的是同一把锁,就能实现同步。 所以说在你的例子中:public class TestSynchronized{
            public static void main(String args[]){
                  TestThread t = new TestThread();
                  new Thread(t).start();//线程1
                  new Thread(t).start();//线程2
                  new Thread(t).start();//线程3
            }
    }class TestThread implements Runnable{
          int num = 100;
          String str = new String();
          public void run(){
                synchronized(str){ //在该例中,这里等效于 synchronized(this){
                        while(true){
                              if(num>0){
                                    try{
                                          Thread.sleep(10);
                                    }catch(Exception e){
                                          e.getMessage();
                                    }
                                    System.out.println(Thread.currentThread().getName()+"this is"+num--);
                              }else{    
                                    System.out.println("over");                    
                                    break;
                              }
                        }
                  }
          }
    }对于 线程1 ,线程2,线程3 来说,在访问 synchronized 所修饰的域时,他们使用的是同一把锁,即 t.str 。因为在 线程1 ,线程2,线程3 中 t.str 是“同一个对象”。
    而如果该成  synchronized(this) 在该例中它与  synchronized(str) 是等效的。因为对于  synchronized(this) 来说 线程1 ,线程2,线程3 使用的也是同一把锁,即 t 。“只要所有线程使用的是同一把锁,就能实现同步。”对于 JVM 它不在乎你使用的锁是哪种类型。它关注的是使用的是否是同一把锁。