解决方案 »

  1.   

    我看到一篇文章上写的   
    .如果一个对象有多个synchronized方法,某一时刻某个线程已经进入到某个synchronzed方法,那么在该方法没有执行完毕前,其他线程无法访问该对象的任何synchronzied 方法的,但可以访问非synchronzied方法。
    这两个方法都是同步方法啊,同一个对象的不同线程怎么能同时访问两个synchronized方法??
      

  2.   

    我看到一篇文章上写的   
    .如果一个对象有多个synchronized方法,某一时刻某个线程已经进入到某个synchronzed方法,那么在该方法没有执行完毕前,其他线程无法访问该对象的任何synchronzied 方法的,但可以访问非synchronzied方法。
    这两个方法都是同步方法啊,同一个对象的不同线程怎么能同时访问两个synchronized方法??
    synchronized方法不是相当于对象锁吗? 同一个对象只能允许同一个线程访问一个synchronized方法
      

  3.   

    我看到一篇文章上写的   
    .如果一个对象有多个synchronized方法,某一时刻某个线程已经进入到某个synchronzed方法,那么在该方法没有执行完毕前,其他线程无法访问该对象的任何synchronzied 方法的,但可以访问非synchronzied方法。
    这两个方法都是同步方法啊,同一个对象的不同线程怎么能同时访问两个synchronized方法??
    synchronized方法不是相当于对象锁吗? 同一个对象只能允许同一个线程访问一个synchronized方法
    你重新跑一下
      

  4.   

    我看到一篇文章上写的   
    .如果一个对象有多个synchronized方法,某一时刻某个线程已经进入到某个synchronzed方法,那么在该方法没有执行完毕前,其他线程无法访问该对象的任何synchronzied 方法的,但可以访问非synchronzied方法。
    这两个方法都是同步方法啊,同一个对象的不同线程怎么能同时访问两个synchronized方法??
    synchronized方法不是相当于对象锁吗? 同一个对象只能允许同一个线程访问一个synchronized方法
    你重新跑一下确实是这样啊 还是有这种情况
      

  5.   

    结果对啊。CPU在一个时间内只运行一个任务这两个方法交替获得CPU执行
      

  6.   

    我看到一篇文章上写的   
    .如果一个对象有多个synchronized方法,某一时刻某个线程已经进入到某个synchronzed方法,那么在该方法没有执行完毕前,其他线程无法访问该对象的任何synchronzied 方法的,但可以访问非synchronzied方法。
    这两个方法都是同步方法啊,同一个对象的不同线程怎么能同时访问两个synchronized方法??
    synchronized方法不是相当于对象锁吗? 同一个对象只能允许同一个线程访问一个synchronized方法
    你重新跑一下确实是这样啊 还是有这种情况
    我跑了好几遍都不是你这个结果
      

  7.   

    我看到一篇文章上写的   
    .如果一个对象有多个synchronized方法,某一时刻某个线程已经进入到某个synchronzed方法,那么在该方法没有执行完毕前,其他线程无法访问该对象的任何synchronzied 方法的,但可以访问非synchronzied方法。
    这两个方法都是同步方法啊,同一个对象的不同线程怎么能同时访问两个synchronized方法??
    synchronized方法不是相当于对象锁吗? 同一个对象只能允许同一个线程访问一个synchronized方法
    你重新跑一下确实是这样啊 还是有这种情况
    我跑了好几遍都不是你这个结果
    为什么我的会出现这种结果? 同一对象的不同线程访问所有的synchronized方法都是同步的吧?
      

  8.   

    同一个对象 不同线程运行不同的synchronized方法应该是互斥的吧 这是是对象锁啊 同一个对象
      

  9.   

    做了几次试验,都没有出现过楼主说的那种情况。
    s1.start();
    try {
    Thread.sleep(5000);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    s1.printAge();
    就算是这样改了,也没出现。
      

  10.   


    奇怪了 我跑十次有六次出现这样的情况
    这个结果是正常的。
    线程的状态有几种
    创建,可运行,运行,睡眠(等待),死亡
    s1.start();这个是可运行状态,但是程序不一定在运行,只是先挂起。由于这里时间特别短,所以CPU就有权先运s1.printAge();所以结果就会是你一开始的那种情况。如果照我改的去运行,时间片长了,就会先运行s1.start();这就不会有你说的那种情况了。
      

  11.   

    恩,如果说sleep()不会释放对象所的话,s1.printAge()是死循环,楼主的第一个输出就是1XXXXXX,说明s1.printAge()已经拿到锁了,那又怎么会再输出age 1:is1呢。
    不过我试了一下楼主的程序,好像就第一次出现输出1XXX后再输出age 1:is1(也可能看走眼了)。之后又试了好多次,都是在age 9:is1之后再输出1XXX的
      

  12.   


    sleep()是不会释放对象的锁 也不会让出cpu 
    但是我试过很多次 很多情况下都是输出1XXX 然后让出对象锁 另外一个线程执行结束 再继续执行原线程 不知道为什么 
      

  13.   


    奇怪了 我跑十次有六次出现这样的情况
    这个结果是正常的。
    线程的状态有几种
    创建,可运行,运行,睡眠(等待),死亡
    s1.start();这个是可运行状态,但是程序不一定在运行,只是先挂起。由于这里时间特别短,所以CPU就有权先运s1.printAge();所以结果就会是你一开始的那种情况。如果照我改的去运行,时间片长了,就会先运行s1.start();这就不会有你说的那种情况了。不好意思啊 截错图了 是这个结果 不理解 
      

  14.   

    正常情况下应该是Student线程start之后没那么快准备好,主线程不等继续走,所以主线程的一点代码很快执行完了,然后才轮到Student线程。所以一般做这种测试在启动线程之后都需要再Thread.sleep()一下等线程准备好。
    出来的第一行结果实在没见过,不会是和上次的结果搞串了吧..
      

  15.   

    没串啊 上一次结果都清空了的
    而且设置一个静态变量count 很清楚就能看出不是上一次的运行结果
      

  16.   

    age 0 is:1
    age 1 is:11xxxxxxxxxxxxxxxxxxxage 2 is:1
    age 3 is:1
    age 4 is:1
    age 5 is:1
    age 6 is:1
    age 7 is:1
    age 8 is:1
    age 9 is:1
    1xxxxxxxxxxxxxxxxxxx
      

  17.   

    和楼主的执行情况不一样。
    运行下面这个例子
    class Student extends Thread {
    private int age; public Student(int age) {
    this.age = age;
    } public synchronized void printAge(){

    for(int i=0;i<10;i++){
    System.err.println("age "+i+" is:"+age);
    }
    }

    public synchronized void printAge(int age) {
    //synchronized(this){
    while (true){
    System.out.println(age+"xxxxxxxxxxxxxxxxxxx");
    try{
    Thread.sleep(5000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    //}

    } public void run() {
    printAge(age);
    }
    }class Test {
    public static void main(String args[]) {
    Student s1 = new Student(1);
    s1.start();
    try{
    Thread.sleep(5000);//主线程休眠,然s1线程执行
    }catch (InterruptedException e) {
    e.printStackTrace();
    }
    s1.printAge();
    }
    }
      

  18.   

    我想我知道问题在哪了,一个线程用的是System.err,一个用的是System.out,这是不同的两个流,eclipse的控制台在输出的时候也许没有处理好,没有实时地输出。说几个方法,你都试试验证下:一个是同样的程序在命令行下测试;一个是统一使用System.out;一个是两个线程里不要输出i,都输出age++然后观察输出结果。
      

  19.   

    奇怪了 我在实验室运行同样的代码 总是出现交叉输出的  家里的电脑就是同步的 
    是的 说的很正确 代码改成这样 
    class Student extends Thread {
    private int age; public Student(int age) {
    this.age = age;
    } public synchronized void printAge() throws InterruptedException{
    Thread.sleep(5000);
    for(int i=0;i<10;i++){
    System.err.println("age "+i+" is:"+age);
    }
    }

    public synchronized void printAge(int age) {
    //synchronized(this){
    while (true){
    System.out.println(age+"xxxxxxxxxxxxxxxxxxx");
    try{
    Thread.sleep(5000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    //}

    } public void run() {
    printAge(age);
    }
    }class Sample {
    public static void main(String args[]) throws InterruptedException {
    Student s1 = new Student(1);
    //s1.start();
    s1.printAge();
    s1.start();
    }
    }
    每次都会交叉输出 按照你说的 SYSTEM.ERR改成SYSTEM.OUT就不会交叉了  就是同步了。。
      

  20.   

    奇怪了 我在实验室运行同样的代码 总是出现交叉输出的  家里的电脑就是同步的 
    是的 说的很正确 代码改成这样 
    class Student extends Thread {
    private int age; public Student(int age) {
    this.age = age;
    } public synchronized void printAge() throws InterruptedException{
    Thread.sleep(5000);
    for(int i=0;i<10;i++){
    System.err.println("age "+i+" is:"+age);
    }
    }

    public synchronized void printAge(int age) {
    //synchronized(this){
    while (true){
    System.out.println(age+"xxxxxxxxxxxxxxxxxxx");
    try{
    Thread.sleep(5000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    //}

    } public void run() {
    printAge(age);
    }
    }class Sample {
    public static void main(String args[]) throws InterruptedException {
    Student s1 = new Student(1);
    //s1.start();
    s1.printAge();
    s1.start();
    }
    }
    每次都会交叉输出 按照你说的 SYSTEM.ERR改成SYSTEM.OUT就不会交叉了  就是同步了。。还是有点不懂  虽然是不同的输出流 但是也都是在synchronized里面 应该不会造成不同步啊?
      

  21.   

    奇怪了 我在实验室运行同样的代码 总是出现交叉输出的  家里的电脑就是同步的 
    是的 说的很正确 代码改成这样 
    class Student extends Thread {
    private int age; public Student(int age) {
    this.age = age;
    } public synchronized void printAge() throws InterruptedException{
    Thread.sleep(5000);
    for(int i=0;i<10;i++){
    System.err.println("age "+i+" is:"+age);
    }
    }

    public synchronized void printAge(int age) {
    //synchronized(this){
    while (true){
    System.out.println(age+"xxxxxxxxxxxxxxxxxxx");
    try{
    Thread.sleep(5000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    //}

    } public void run() {
    printAge(age);
    }
    }class Sample {
    public static void main(String args[]) throws InterruptedException {
    Student s1 = new Student(1);
    //s1.start();
    s1.printAge();
    s1.start();
    }
    }
    每次都会交叉输出 按照你说的 SYSTEM.ERR改成SYSTEM.OUT就不会交叉了  就是同步了。。还是有点不懂  虽然是不同的输出流 但是也都是在synchronized里面 应该不会造成不同步啊?我先说的最后一点你测试过没有?你代码里的输出只能说是输出顺序,不代表就是执行顺序。同一个流不管怎样肯定会顺序打印,两个流会如何同时打印在一个控制台上那就不确定了。
      

  22.   

    奇怪了 我在实验室运行同样的代码 总是出现交叉输出的  家里的电脑就是同步的 
    是的 说的很正确 代码改成这样 
    class Student extends Thread {
    private int age; public Student(int age) {
    this.age = age;
    } public synchronized void printAge() throws InterruptedException{
    Thread.sleep(5000);
    for(int i=0;i<10;i++){
    System.err.println("age "+i+" is:"+age);
    }
    }

    public synchronized void printAge(int age) {
    //synchronized(this){
    while (true){
    System.out.println(age+"xxxxxxxxxxxxxxxxxxx");
    try{
    Thread.sleep(5000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    //}

    } public void run() {
    printAge(age);
    }
    }class Sample {
    public static void main(String args[]) throws InterruptedException {
    Student s1 = new Student(1);
    //s1.start();
    s1.printAge();
    s1.start();
    }
    }
    每次都会交叉输出 按照你说的 SYSTEM.ERR改成SYSTEM.OUT就不会交叉了  就是同步了。。还是有点不懂  虽然是不同的输出流 但是也都是在synchronized里面 应该不会造成不同步啊?我先说的最后一点你测试过没有?你代码里的输出只能说是输出顺序,不代表就是执行顺序。同一个流不管怎样肯定会顺序打印,两个流会如何同时打印在一个控制台上那就不确定了。
    明白了 谢谢。