编写一个程序,启动三个线程,三个线程的ID分别是A,B,C;,每个线程将自己的ID值在屏幕上打印10遍,打印顺序是ABCABC...
package practice;
public class ThreeThread extends Thread {
    
    
    public static void main(String[] args) {
        MyObject ob = new MyObject();
        new Thread(new Runnable(){
            @Override
            public void run() {
                // TODO Auto-generated method stub
                for(int i = 0 ; i<10 ; i++)
                    ob.printA();
            }
            
        }).start();
        new Thread(new Runnable(){
            @Override
            public void run() {
                // TODO Auto-generated method stub
                for(int i = 0 ; i<10 ; i++)
                    ob.printB();
            }
            
        }).start();
        new Thread(new Runnable(){
            @Override
            public void run() {
                // TODO Auto-generated method stub
                for(int i = 0 ; i<10 ; i++)
                    ob.printC();
            }
            
        }).start();
    }}class MyObject  {
    
    private  int flag = 1;
    
    public synchronized void printA(){
        while(flag != 1){
            try {
                this.wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
            System.out.print("A");
            flag = 2;
            this.notifyAll();
            
        
        
    }
   
    public synchronized void printB(){
        while(flag != 2){
            try {
                this.wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
            System.out.print("B");
            flag = 3;
            this.notifyAll();
            
        
        
    }
     public synchronized void printC(){
        while(flag != 3){
            try {
                this.wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
            System.out.println("C");
            flag = 1;
            this.notifyAll();
            
        
        
    }
    
}
这里为何要在每个方法前加上synchronized呢,加上synchronized不是为了同步方法吗?可是这三个线程各自调用不同的方法,不会影响其他的方法啊,求大佬解答

解决方案 »

  1.   

    加synchronized是为了让使用wait方法啊弟弟,使用wait方法必须获取对象的监视器。
    给你篇文章,理解的透透的
    https://www.cnblogs.com/dreamowneryong/p/11607742.html
      

  2.   

    原来连接是这么插入的
    https://www.cnblogs.com/dreamowneryong/p/11607742.html
      

  3.   

    synchronize方法,是针对这个对象进行同步,因为你线程里面都是指向同一个对象的方法,因此达到了同步的效果
      

  4.   

    如果synchronized()里包含的是相同的一个对象,就能实现不同线程之间的竞争关系。如果每个线程各自new了一个对象来synchronized,就没啥意义了。
      

  5.   

    三个不同的方法没有问题,但这三个方法必须有且只有一个能同时运行,因为他们只有一个方法能拿到锁。其他两个没有拿到锁就无法运行。
    在这里的锁默认是对象锁
    这三个方法虽然不同,但他们都有访问共同的资源,即对象锁对应对象中的flag,在访问过程中,很可能被其他线程修改
    同时wait方法也必须在对象锁中调用
      

  6.   

    因为你使用了共享变量  flag
      

  7.   

    如果你不加的话,你看一下 flay就不是透明的
      

  8.   

    虽然是3个不同的方法,但是输出顺序有要求,如果不加synchronize,打印顺序就是随机的,不能保证顺序ABCABC...
    所以要第一个线程执行完printA以后才能第二个线程才能执行printB,printB完以后第三个线程才能执行printC,printC完以后第一个线程才能重新执行printA,依次类推
      

  9.   

    我在执行printA的时候flag还是1,其他两个方法就算不加synchronized也不会被执行啊
      

  10.   

    是不是我不加synchronized 使用wait就会报错,因为没获得对象锁
      

  11.   

    flag确实是共享变量,但是如果printA不改变他的值,其他两个方法根本不能运行啊
      

  12.   

    printA执行一次后flag就变了,之后printA线程先执行还是printB先执行就不可预测了是的,wait方法需要获得对象锁,否则抛出异常