修改别人的错误多线程

话不多说,先上错误代码:

  1
  2 /**
  3  * 编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,
  4  * 要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推
  5  * @author Fantastic_Rebo
  6  *
  7  */
  8 
  9 public class Play2 {
 10     static public int num=1;
 11     public static void main(String[] args) throws InterruptedException {
 12         Object o=new Object();
 13         A2 a2=new A2(o);
 14         B2 b2=new B2(o);
 15         C2 c2=new C2(o);
 16         
 17         Thread t1=new Thread(a2,"A---");
 18         Thread t2=new Thread(b2,"B---");        
 19         Thread t3=new Thread(c2,"C---");
 20         
 21         t1.start();
 22         t2.start();
 23         t3.start();
 24         
 25         for (int i = 1; i >0; i++) {
 26             if(i%3==1) {
 27                 t1.start();
 28             }else if(i%3==2) {
 29                 t2.start();
 30             }else if(i%3==0) {
 31                 t3.start();
 32             }
 33         }
 34         
 35         
 36     }
 37 }
 38 class A2 implements Runnable{
 39     Object o;
 40     public A2(Object o) {
 41         super();
 42         this.o = o;
 43     }
 44     @Override
 45     public void run() {
 46     
 47             if(num%3==1) {
 48                 num++;
 49                 for (int i = 1; i <=10; i++) {
 50                     synchronized (o) {
 51                         o.notify();
 52                         System.out.println(Thread.currentThread().getName()+i);
 53                         try {
 54                             o.wait();
 55                         } catch (InterruptedException e) {
 56                             e.printStackTrace();
 57                         }
 58                     }
 59                 }    
 60             }else {
 61                 try {
 62                     o.wait();
 63                 } catch (InterruptedException e) {
 64                     // TODO Auto-generated catch block
 65                     e.printStackTrace();
 66                 }
 67             }
 68         
 69     }
 70     
 71 }
 72 class B2 implements Runnable{
 73     Object o;
 74     int num;
 75     public B2(Object o) {
 76         super();
 77         this.o = o;
 78     }
 79     @Override
 80     public void run() {
 81             if(num%3==2) {
 82                 num++;
 83                 for (int i = 1; i <=10; i++) {
 84                     synchronized (o) {
 85                         o.notify();
 86                         System.out.println(Thread.currentThread().getName()+i);
 87                         try {
 88                             o.wait();
 89                         } catch (InterruptedException e) {
 90                             e.printStackTrace();
 91                         }
 92                     }
 93                 }    
 94             }else {
 95                 try {
 96                     o.wait();
 97                 } catch (InterruptedException e) {
 98                     // TODO Auto-generated catch block
 99                     e.printStackTrace();
100                 }
101             }
102         
103     }
104 }
105 class C2 implements Runnable{
106     Object o;
107     private int num;
108     public C2(Object o) {
109         super();
110         this.o = o;
111     }
112     @Override
113     public void run() {
114         
115             if(num%3==0) {
116                 num++;
117                 for (int i = 1; i <=10; i++) {
118                     synchronized (o) {
119                         o.notify();
120                         System.out.println(Thread.currentThread().getName()+i);
121                         try {
122                             o.wait();
123                         } catch (InterruptedException e) {
124                             e.printStackTrace();
125                         }
126                     }
127                 }    
128             }else {
129                 try {
130                     o.wait();
131                 } catch (InterruptedException e) {
132                     // TODO Auto-generated catch block
133                     e.printStackTrace();
134                 }
135             }    
136         
137     }
138     
139 }

第一次修改:



public class Play2 {
    static int num = 1;
    public static class A2 implements Runnable {
        int count = 1;
        @Override
        public void run() {
            while (count <= 10) {
                synchronized (Play2.class) {
                    if (num % 3 == 0) {
                        System.out.println(Thread.currentThread().getName() + count++);
                        num++;
                    }
                    Play2.class.notifyAll();
                    try {
                        Play2.class.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    public static class B2 implements Runnable {
        int countb = 1;
        @Override
        public void run() {
            while (countb <= 10) {
                synchronized (Play2.class) {
                    if (num % 3 == 1) {
                        System.out.println(Thread.currentThread().getName() + countb++);
                        num++;
                    }
                    Play2.class.notifyAll();
                    try {
                        Play2.class.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                }
            }
    }
    public static class C2 implements Runnable {
        int countc = 1;
        @Override
        public void run() {
            while(countc <= 10) {
            synchronized (Play2.class) {
                if (num % 3 == 2) {
                    System.out.println(Thread.currentThread().getName() + countc++);
                    num++;
                }
                Play2.class.notifyAll();
                try {
                    Play2.class.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            }
        }
    }
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(new A2(), "A---");
        Thread t2 = new Thread(new B2(), "B---");
        Thread t3 = new Thread(new C2(), "C---");
        t1.start();
        t2.start();
        t3.start();
    }
}

但是很显然,和人家原来思想是不一样的,所以我又进行了第二次修改:



/**
 * 编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,
 * 要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推
 * 
 * @author Fantastic_Rebo
 *
 */

public class Play3 {

    public static void main(String[] args) throws InterruptedException {
        Object o = new Object();
        A2 a2 = new A2(o);
        B2 b2 = new B2(o);
        C2 c2 = new C2(o);

        Thread t1 = new Thread(a2, "A---");
        Thread t2 = new Thread(b2, "B---");
        Thread t3 = new Thread(c2, "C---");

        t1.start();
        t2.start();
        t3.start();

        /*
         * for (int i = 1; i >0; i++) { if(i%3==1) { t1.start(); }else if(i%3==2) {
         * t2.start(); }else if(i%3==0) { t3.start(); } }
         */

    }
}
/**
 * @description 整体思路:首先我看你的代码是想要单独的写3个类,这边写到一个java文件中是不合适的;其次在run方法内部多次使用锁容易出错,
 *                 而且代码复杂,不符合我们java简单的设计原则;第三,在你的代码中明显是想要使用加上主类在内的4个类公用一份资源,因为你需要
 *                 传递一个变量,那么必须使用一个中间值作为参数传递的媒介,你这边没有,导致参数没法传递。
 *     修改思路:
 *         一般情况下,我们要对多线程进行精准控制,都是写在一个类中,子线程的类用内部类来写,你可以在主类中定义一个全局变量,这样做的好处是你可以在
 * 内部类中公用这个全局变量,对于线程的控制会更加精准;但是一时想不到或者不想用这种方法来做的话,也可以用现在这个例子来做,那就是我们定义一个主类,
 * 然后在定义多个线程类,另外还需要定义一个媒介类(注意:这个类是用于传递参数用的,那么为了能精准控制,而且联系到各个类,那么这个类不能在每个类中都
 * 新new一个对象,所以我们只能是将这个类中的方法属性定义为static的,这样一来,我们在勒种可以直接调用,就实现了公用资源的目的)。在线程类中,我
 * 们在使用过媒介类后,就像这个例子一样,需要对媒介类中的传参属性进行变更,那么其他线程得到的属性就是刚刚变更的值,这样资源共享实现,线程精准控制
 * 通过这一份资源也得到了很好的控制。
 * 
 * @author lh
 *
 */
class A2 implements Runnable {
    Object o;
    public A2(Object o) {
        super();
        this.o = o;
    }
    @Override
    public void run() {
        int count = 1;
        synchronized (o) {
            while (count <= 10) {
                int num = StringUtil.getNumber();
                if (num % 3 == 0) {
                    System.out.println(Thread.currentThread().getName() + count);
                    StringUtil.setNumber(++num);
                    count++;
                }
                o.notifyAll();
                try {
                    o.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            o.notifyAll();
        }
    }
}

class B2 implements Runnable {
    Object o;

    public B2(Object o) {
        super();
        this.o = o;
    }

    @Override
    public void run() {
        int count = 1;
        synchronized (o) {
            while (count <= 10) {
                int num = StringUtil.getNumber();
                if (num % 3 == 1) {
                    System.out.println(Thread.currentThread().getName() + count);
                    StringUtil.setNumber(++num);
                    count++;
                }
                o.notifyAll();
                try {
                    o.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            o.notifyAll();
        }
    }
}

class C2 implements Runnable {
    Object o;

    public C2(Object o) {
        super();
        this.o = o;
    }

    @Override
    public void run() {
        int count = 1;
        synchronized (o) {
            while (count <= 10) {
                int num = StringUtil.getNumber();
                if (num % 3 == 2) {
                    System.out.println(Thread.currentThread().getName() + count);
                    StringUtil.setNumber(++num);
                    count++;
                }
                o.notifyAll();
                try {
                    o.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            o.notifyAll();
        }
    }
}

另外还有一个类,我作为中间媒介存在:

public class StringUtil {
    static int num = 1;
    public static int getNumber() {
        
        return num;
    }
    public static void setNumber(int num) {
        StringUtil.num = num;
    }
}

到此,终于按照他的想法将他想要代码实现了。

posted @ 2018-01-05 15:48  昔日风华  阅读(242)  评论(0)    收藏  举报