引用迅雷面试题
http://topic.csdn.net/u/20091129/21/4bbf398d-431a-4f8e-accc-b8de6572b8af.html?1357
我写了一个实现,线程用得不熟,有人能给出一个更好些的实现吗?
class A extends Thread {
public A(String name){super(name);}
    @Override
    public void run() {     System.out.println("id-->"+this.getId()+"name-->"+getName());
     
    }
}class B extends Thread {    private A a;    public B(A a,String name) {
        super(name);
        this.a = a;
    }    @Override
    public void run() {
        try {
            a.join();
        } catch (InterruptedException ie) {
            ie.printStackTrace();
        }
      System.out.println("id-->"+this.getId()+"name-->"+getName());    }
}class C extends Thread {    private B b;    public C(B b,String name) {
        super(name);
        this.b = b;
    }    @Override
    public void run() {
        try {
            b.join();
        } catch (InterruptedException ie) {
            ie.printStackTrace();
        }
      System.out.println("id-->"+this.getId()+"name-->"+getName());    }
}public class ConABC10 {    public static void main(String[] args) {  long s=System.currentTimeMillis();
        int i = 0;        while (i++ < 10) {            A a = new A("A");
            B b = new B(a,"B");
            C c = new C(b,"C");            a.start();
            b.start();
            c.start();        }
System.out.println(System.currentTimeMillis()-s);
    }
}

解决方案 »

  1.   


    public class TestABC { public static void main(String[] args) throws Exception {
    for (int i = 0; i < 10; i++) {
    Thread a = new Thread(new Runner("A"));
    a.start();
    a.join();
    Thread b = new Thread(new Runner("B"));
    b.start();
    b.join();
    Thread c = new Thread(new Runner("C"));
    c.start();
    c.join();
                           System.out.println();
    }
    }}class Runner implements Runnable {
    private String name; public Runner(String name) {
    this.name = name;
    } public void run() {
    System.out.println(name);
    }
    }
      

  2.   

    ...
    thread.join();
    等待该线程终止
    这和顺序打印有何区别?
      

  3.   

    import java.util.concurrent.atomic.AtomicInteger;public class Print extends Thread{
    private AtomicInteger synObj;
    private int count;
    private String s;
    private int flag;
    private int total = 0;

    public Print(int count,AtomicInteger atomicInteger,String s,int flag) {
    this.count = count;
    this.synObj = atomicInteger;
    this.s = s;
    this.flag = flag;
    }
    public void run() {
    while(true) {
    synchronized(synObj) {
    if(synObj.intValue()%3 == flag) {
    total++;
    synObj.set(synObj.intValue()+1);
    System.out.println(s);
    synObj.notifyAll();
    if(total == count) {
    break;
    }
    }else {
    try{
    synObj.wait();
    }catch(Exception e){
    e.printStackTrace();
    }
    }
    }
    }
    }
    public static void main(String[]args) throws Exception {
    AtomicInteger synObj = new AtomicInteger(0);
    Print a = new Print(10,synObj,"A",0);
    Print b = new Print(10,synObj,"B",1);
    Print c = new Print(10,synObj,"C",2);
    a.start();
    b.start();
    c.start();
    }
    }
    这个可供参考
      

  4.   

    public class TestABC { public static void main(String[] args) throws Exception {
    Thread a = new Thread(new Runner("A", 0));
    Thread b = new Thread(new Runner("B", 1));
    Thread c = new Thread(new Runner("C", 2));
    a.start();
    b.start();
    c.start();
    a.join();
    b.join();
    c.join();
    }
    }class Runner implements Runnable {
    private String name;
    private int index; private static int g_index = 0;
    private static int g_count = 0; private static final Object lock = new Object(); public Runner(String name, int index) {
    this.name = name;
    this.index = index;
    g_count++;
    } public void run() {
    for (int i = 0; i < 10; i++) {
    synchronized (lock) {
    while (g_index != index) {
    try {
    lock.wait();
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    System.out.println(name);
    g_index = (g_index + 1) % g_count;
    lock.notifyAll();
    }
    }
    }
    }
      

  5.   

    似乎思路和#4的似乎差不多再修改下,避免一点问题public class TestABC { public static void main(String[] args) throws Exception {
    System.out.println("start");
    Thread a = new Thread(new Runner("A"));
    Thread b = new Thread(new Runner("B"));
    Thread c = new Thread(new Runner("C"));
    a.start();
    b.start();
    c.start();
    a.join();
    b.join();
    c.join();
    System.out.println("finish");
    }
    }class Runner implements Runnable {
    private String name;
    private int index; private static int g_index = 0;
    private static int g_count = 0; private static final Object lock = new Object(); public Runner(String name) {
    this.name = name;
    this.index = g_count++;
    } public void run() {
    for (int i = 0; i < 10; i++) {
    synchronized (lock) {
    while (g_index != index) {
    try {
    lock.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    System.out.println(name);
    g_index = (g_index + 1) % g_count;
    lock.notifyAll();
    }
    }
    }
    }
      

  6.   


    思路也很好.但是5.0前的传统方法.共享lock的是一个对象lock,数数的用g_index
    一点个人见解: 1) g_index和g_count 应该加上volatile关键声明吧,要不虚拟机优化的原因,run方法内会有本地拷贝?2)wait()在while循环中,这是很好的,但外面套了个for1-10总觉得有些怪异
      

  7.   


    以前做过,运用concurrent包http://topic.csdn.net/u/20100801/12/e5265ef6-eaed-4cf7-a524-1e5592fa5967.htmlpackage pcenshao.thread; import java.util.concurrent.Semaphore; public class SemaphoreABC { static class T extends Thread{ Semaphore me; Semaphore next; public T(String name,Semaphore me,Semaphore next){ super(name); this.me = me; this.next = next; } @Override public void run(){ for(int i = 0 ; i < 10 ; i ++){ try { me.acquire(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(this.getName()); next.release(); } } } public static void main(String[] args) { Semaphore aSem = new Semaphore(1); Semaphore bSem = new Semaphore(0); Semaphore cSem = new Semaphore(0); T a = new T("A",aSem,bSem); T b = new T("B",bSem,cSem); T c = new T("C",cSem,aSem); a.start(); b.start(); c.start(); } }
      

  8.   

    4楼,我只想说,佩服,你的代码太好啦!
    1)java.util.concurrent.atomic.AtomicInteger这个类是亮点.一直觉得java se 5.0的concurrent包很强大,却一直不是熟悉,今天我想是时候找本书学习一下了.
       这个类解决了传统写法的一些问题 .我的体会是.你各个线程之间如果共享的是int,char等primitive类型肯定是不行的,因为它们不是对象.2)Integer,Character包装类也是不成的,因为他们是不变类型,同理String 类型也是不成的,因为不变类型,改变内容返回的是新的地址,而不是在原有地址上.3)自己写个类吧,总觉得也不是那么回事
    2) 构造函数写的很灵活
    3) run方法写得也帅气.看来对同步的理解很深入.
      

  9.   


    虽然原理暂时还不明白,但一看就知道是个concurrent包的高人
      

  10.   

    以下是我自己写的一个改进方法,和4楼9楼相比,差距是明显的.
    1)除long,double外的primitive类型应该读和写都是原子操作.再加上volatile关键字应该没有问题 的
    2)谁能找找原理上有没有什么BUG之类的,不胜感谢class A extends Thread {    public A(String name) {
            super(name);
        }    @Override
        public void run() {
            while (true) {
                if (ConABC10.times == 10) {
                    break;
                } else if (ConABC10.flag == 'A') {
                    System.out.println("id-->" + this.getId() + "name-->" + getName());
                    ConABC10.flag = 'B';
                } else {
                    yield();
                }
            }
        }
    }class B extends Thread {    public B( String name) {
            super(name);    }    @Override
        public void run() {        while (true) {
                if (ConABC10.times == 10) {
                    
                    break;
                } else if (ConABC10.flag == 'B') {
                    System.out.println("id-->" + this.getId() + "name-->" + getName());
                    ConABC10.flag = 'C';
                } else {
                    yield();
                }
            }    }
    }class C extends Thread {
        public C(String name) {
            super(name);    }    @Override
        public void run() {
            while (true) {
                if (ConABC10.times == 10) {
                     System.out.println(System.currentTimeMillis() - ConABC10.s);
                    break;
                } else if (ConABC10.flag == 'C') {
                    System.out.println("id-->" + this.getId() + "name-->" + getName());
                    ConABC10.flag = 'A';
                    ConABC10.times++;
                } else {
                    yield();
                }
            }
        }
    }public class ConABC10 {    public static volatile char flag = 'A';
        public static volatile int times = 0;
       public static volatile long s;
        public static void main(String[] args) {         s = System.currentTimeMillis();
            int i = 0;
            A a1 = new A("A");
            B b1 = new B("B");
            C c1 = new C("C");
              a1.start();
            b1.start();
            c1.start();
              
        }
    }
      

  11.   

    4楼的答案貌似有死锁可能。
    加上一行
    }else {
                        try{
                            //add
                            synObj.notifyAll();
                            synObj.wait();
                        }catch(Exception e){
                            e.printStackTrace();
                        }
                    }