昨天看到一个帖子要求用三个线程,顺序的打印ABC。打10遍(看这题出的,都要求顺序执行了还要用多线程,够变态),我看了看回复,一堆写的乱七八糟的。回家恶补了一下多线程。就是如下结果。只要你贴个比我这个好的,分就是你的啦
import java.util.ArrayList;
import java.util.List;public class Startup { /**
 * @param args
 */
public static void main(String[] args) {
Startup s = new Startup();
s.demo();
} public void demo() {
Deamon deamon = new Deamon("deamon");
deamon.setDaemon(true);
deamon.start();
} private class Deamon extends Thread {
public Deamon(String name) {
super(name);
} public void run() {
List<LazyPrinter> theLazy = new ArrayList<LazyPrinter>(); theLazy.add(new LazyPrinter("A"));
theLazy.add(new LazyPrinter("B"));
theLazy.add(new LazyPrinter("C"));
for (LazyPrinter p : theLazy) {
synchronized (this) {
p.start();
}
} while (true) {
for (LazyPrinter p : theLazy) {
synchronized (p) {
p.notify();
try {
p.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println();
} } } /**
 * 每次被调度后打印一行就开始休息
 * 
 * @author wWX31016
 * 
 */
private class LazyPrinter extends Thread {
public LazyPrinter(String name) {
super(name);
} public void run() {
for (int i = 0; i < 10; i++) {
synchronized (this) {
this.notify();
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print(this.getName()); }
}
}
}}

解决方案 »

  1.   

    20几行代码就搞定的东西,搞这么复杂这么多干嘛public class Test {
    public static void main(String... a) throws Exception {
    Thread t1 = new Thread(new T("A"));
    t1.start();
    t1.join();
    Thread t2 = new Thread(new T("B"));
    t2.start();
    t2.join();
    Thread t3 = new Thread(new T("C"));
    t3.start();
    t3.join();
    }
    }
    class T implements Runnable {
    private String value;
    public T(String value) {
    this.value = value;
    }
    public void run() {
    System.out.println(value);
    }
    }
      

  2.   

    再减几行
    public class Test {
    public static void main(String... a) throws Exception {
    start("A");
    start("B");
    start("C");
    }
    private static void start(String value) throws Exception {
    Thread t = new Thread(new T(value));
    t.start();
    t.join();
    }
    }
    class T implements Runnable {
    private String value;
    public T(String value) {
    this.value = value;
    }
    public void run() {
    System.out.println(value);
    }
    }
      

  3.   

    加上打10遍
    public class Test {
    public static void main(String... a) throws Exception {
    for(int i=0; i<10; i++) {
    start("A");
    start("B");
    start("C");
    }
    }
    private static void start(String value) throws Exception {
    Thread t = new Thread(new T(value));
    t.start();
    t.join();
    }
    }
    class T implements Runnable {
    private String value;
    public T(String value) {
    this.value = value;
    }
    public void run() {
    System.out.println(value);
    }
    }
      

  4.   


    我总觉得此题的用意是考察同步,而不是join
      

  5.   

    什么乱七八糟的,你上面写滴就是for (int i = 0; i < 10; i++) {
        System.out.println("ABC");
    }/*
                theLazy.add(new LazyPrinter("A"));
                theLazy.add(new LazyPrinter("B"));
                theLazy.add(new LazyPrinter("C"));
    */
    /*然后这里~~,由这个for循环可以看出,你三个线程和一个线程 
               theLazy.add(new LazyPrinter("ABC"));
      是没有区别的,然后再总的看你的程序结构,就会发再你根本没用到线程,
    LZ,你说为什么要用线程,什么情况用线程??
                    for (LazyPrinter p : theLazy) {
                        synchronized (p) {
                            p.notify();
                            try {
                                p.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
    */
      

  6.   

    多线程同步啊,用lock 也可以,LZ是要减少代码量?晚上写个贴上来,呵呵
      

  7.   

    import java.io.*;
    public class print
    {
    public static void main(String[] arg)
    {
    T t=new T();
    Thread t1=new Thread(t,"A");
    Thread t2=new Thread(t,"B");
    Thread t3=new Thread(t,"C");
    t1.start();
    t2.start();
    t3.start();

    }
    } class T implements Runnable
    {
    int a=0;
    public void run()
    {
    while(a<30)
    {
          print();
       }
      
    }
    public synchronized void  print()
    {

    if(a%3+'A'==Thread.currentThread().getName().charAt(0))
    {
     System.out.print((char)(a%3+'A'));
             a++;
          notifyAll();
    }
    else 
    try{
    wait();
    }catch(java.lang.InterruptedException ie){}
    }
    }
      

  8.   

    对于题目的需求,不一定要用wait,通过变量控制也可以:public class PrintABCTest { /**
     * @param args
     */
    public static void main(String[] args) {
    TaskThread A = new TaskThread("A");
    TaskThread B = new TaskThread("B");
    TaskThread C = new TaskThread("C");
    A.setPreTask(C);
    B.setPreTask(A);
    C.setPreTask(B);
    C.setCurrentDone(true);
    A.start();
    B.start();
    C.start();
    }

    static class TaskThread extends Thread {

    private boolean currentDone = false;
    private String name;
    private TaskThread preTask;

    public TaskThread(String name) {
    this.name = name;
    }

    public void run() {
    int count = 0;
    while(count < 10) {
    if(preTask != null && preTask.isCurrentDone() && !isCurrentDone()) {
    System.out.print(name);
    setCurrentDone(true);
    preTask.setCurrentDone(false);
    ++count;
    }
    try {
    Thread.sleep(500);
    } catch (InterruptedException e) {

    }
    }
    }

    public synchronized void setCurrentDone(boolean isDone) {
    this.currentDone = isDone;
    }

    public synchronized boolean isCurrentDone() {
    return currentDone;
    }

    public void setPreTask(TaskThread preTask) {
    this.preTask = preTask;
    }
    }
    }
      

  9.   

    顺序打印 10 次 ABC 与使用单线程输出有啥区别?
      

  10.   

    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;public class Test {    public static void main(String[] args) {
            Worker t = new Worker(10, "A", "B", "C");
            t.execute(10);
        }
    }class Worker {    private String next;
        private Runnable[] workers;    public Worker(int repeat, String... output) {
            this.next = output[0];
            initWorkers(output);
        }    public void execute(int repeat) {
            ExecutorService es = Executors.newFixedThreadPool(workers.length);
            for(int i = 0; i < repeat; i++) {
                es.submit(workers[i % workers.length]);
            }
            es.shutdown();
        }    private void initWorkers(String... output) {
            workers = new Runnable[output.length];
            for(int i = 0, k = output.length; i < k; i++) {
                workers[i] = new OutputWorker(output[i], output[(i + 1) % k]);
            }
        }    private synchronized void print(OutputWorker ow) {
            while(!ow.output.equals(next)) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(ow.output);
            this.next = ow.next;
            notifyAll();
        }    private class OutputWorker implements Runnable {        private String output;
            private String next;        public OutputWorker(String output, String next) {
                this.output = output;
                this.next = next;
            }        @Override
            public void run() {
                print(this);
            }
        }
    }
      

  11.   

    首先,楼主的代码有问题,多运行几遍就会发现并不是每次都成功
    jixiuf@jf /tmp $ java Startup
    AB          //这里少个C
    ABC
    ABC
    ABC
    ABC
    ABC
    ABC
    ABC
    Ajixiuf@jf /tmp $ java Startup
    ABC
    ABC
    ABC
    ABC
    ABC
    ABC
    ABC
    ABC
    ABC
    ABCjixiuf@jf /tmp $ 
      

  12.   

    http://www.blogjava.net/hankchen/archive/2009/12/29/307680.html
      

  13.   

    不用同步,只需互斥访问即可:
    import java.io.*;
    public class print
    {
    public static void main(String[] arg)
    {
    T t=new T();
    Thread t1=new Thread(t,"A");
    Thread t2=new Thread(t,"B");
    Thread t3=new Thread(t,"C");
    t3.start();
    t2.start();
    t1.start();

    }
    } class T implements Runnable
    {
     int a=0;
    public void run()
    {
    while(true)
    {
          synchronized(this)
          {
           if(a>=30) break;
           System.out.print((char)(a%3+'A'));
             a++;
            
          }
       }
      
    }

    }
      

  14.   


    /**
     * @author Redduke
     */
    public class ABC {
    public static void main(String[] args) {
    Signal signal = new Signal();
    signal.setState(Signal.STATE.A);
    new ThreadA(signal).start();
    new ThreadB(signal).start();
    new ThreadC(signal).start();
    } /*
     * 线程共享信号
     */
    static class Signal {
    static enum STATE {
    A, B, C;
    }; private STATE state; public synchronized STATE getState() {
    return state;
    } public synchronized void setState(STATE state) {
    this.state = state;
    }
    } /*
     * 打印A的线程
     */
    static class ThreadA extends Thread {
    final Signal signal; public ThreadA(Signal signal) {
    this.signal = signal;
    } public void run() {
    try {
    for (int i = 0; i < 10; i++) {
    synchronized (signal) {
    while (signal.getState() != Signal.STATE.A)
    signal.wait();
    System.out.print("A");// 打印A
    signal.setState(Signal.STATE.B);// 通知B
    signal.notifyAll();
    }
    }
    } catch (InterruptedException ie) {
    ie.printStackTrace();
    }
    }
    } /*
     * 打印B的线程
     */
    static class ThreadB extends Thread {
    final Signal signal; public ThreadB(Signal signal) {
    this.signal = signal;
    } public void run() {
    try {
    for (int i = 0; i < 10; i++) {
    synchronized (signal) {
    while (signal.getState() != Signal.STATE.B)
    signal.wait();
    System.out.print("B");// 打印B
    signal.setState(Signal.STATE.C);// 通知C
    signal.notifyAll();
    }
    }
    } catch (InterruptedException ie) {
    ie.printStackTrace();
    }
    }
    } /*
     * 打印C的线程
     */
    static class ThreadC extends Thread {
    final Signal signal; public ThreadC(Signal signal) {
    this.signal = signal;
    } public void run() {
    try {
    for (int i = 0; i < 10; i++) {
    synchronized (signal) {
    while (signal.getState() != Signal.STATE.C)
    signal.wait();
    System.out.println("C");// 打印C
    signal.setState(Signal.STATE.A);// 通知A
    signal.notifyAll();
    }
    }
    } catch (InterruptedException ie) {
    ie.printStackTrace();
    }
    }
    }
    }
      

  15.   

    #19楼 的做法是
    规定每个线程的功能,然后根据next 标识来顺序执行 线程(互斥)
    扩展性强#27楼 的做法是
    通过一个共享变量,线程执行一次,输出,然后将变量变成下一个值
    扩展性弱,但代码简洁学习学习!都是高手
      

  16.   

    package csdn.test;import java.util.Observable;
    import java.util.Observer;public class ABCTest {
    public static void main(String[] args) {
    PrintTarget pta = new PrintTarget();
    PrintTarget ptb = new PrintTarget();
    PrintTarget ptc = new PrintTarget();
    pta.setFirst(true);
    pta.addObserver(ptb);
    ptb.addObserver(ptc);
    ptc.addObserver(pta);
    Thread tha = new Thread(pta, "A");
    Thread thb = new Thread(ptb, "B");
    Thread thc = new Thread(ptc, "C");
    thc.start();
    thb.start();
    tha.start();
    while (tha.isAlive() && thb.isAlive() && thc.isAlive()) {
    try {
    Thread.sleep(1000l);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    System.out.println("done");
    }}class PrintTarget extends Observable implements Runnable, Observer {
    private Object lock = new Object();
    private boolean first = false;
    private int count = 0; public void setFirst(boolean first) {
    this.first = first;
    } public void run() {
    if (first) {
    printName();
    }
    while (count < 10) {
    synchronized (lock) {
    try {
    lock.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    printName();
    }
    } private void printName() {
    System.out.println(Thread.currentThread().getName());
    count++;
    this.setChanged();
    this.notifyObservers();
    } public void update(Observable o, Object arg) {
    synchronized (lock) {
    lock.notifyAll();
    }
    }}
    试试这个
      

  17.   

    大家写的都很好啊。学了几招
    buffoon把计数的++和打印放到了一个方法里。开始我还好奇你的怎么没有多打印一个A呢不过我没看懂你这个程序怎么工作的阿。
    比如你的pta 执行了printName之后。会触发它的Observer ptb的update方法。这时候它notify了谁?自己触发自己的run继续执行么?
      

  18.   

    dingshiqi555你这个答案太有迷惑性了。你的三个线程打印什么不是由它自己本身携带的信息决定的。
      

  19.   


    pta的notifyObservers(),会调用ptb.update()方法,在pta所在的线程里面,激活ptb的锁对象。ptb被激活,继续执行下面的语句