0

我必须使用两个线程,一个线程打印所有小于 10 的奇数,另一个打印小于 10 的偶数,并且最终输出应该按顺序排列。

我已经实现了如下。我想使用同步方法做同样的事情吗?怎么做?

class printodd extends Thread{

public void run() {

    super.run();
    for(int i=0;i<10;i=i+2){
        System.out.println("even "+i);
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {

        e.printStackTrace();
    }
    }
 }
} 
class printeven extends Thread{
public void run() {

    super.run();
    for(int i=1;i<10;i=i+2)
    {
        System.out.println("odd "+i);
        try {
            Thread.sleep(1050);
        } catch (InterruptedException e) {

            e.printStackTrace();
        }
    }
}
}
public class PrintNumSeq{
public static void main(String[] args) {
    printodd p=new printodd();
    printeven e=new printeven();
    e.start();
    p.start();
}
}
4

4 回答 4

0

尝试这个

public class PrintNumSeq extends Thread {
    static Object lock = new Object();
    static int n;
    int even;

    PrintNumSeq(int r) {
        this.even = r;
    }

    public void run() {
        try {
            synchronized (lock) {
                for (;;) {
                    while ((n & 1) != even) {
                        lock.wait();
                    }
                    n++;
                    lock.notify();
                    if (n > 10) {
                        break;
                    }
                    System.out.println(n);
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new PrintNumSeq(1).start();
        new PrintNumSeq(0).start();
    }
}

输出

1
2
3
4
5
6
7
8
9
10
于 2013-06-08T15:00:38.023 回答
0
public class SequentialThreadPrinter {
    public static void main(String[] args) {
        AtomicInteger counter = new AtomicInteger(0);
        EvenThread even = new EvenThread("even", counter);
        OddThread odd = new OddThread("odd", counter);
        even.start();
        odd.start();
    }
}

private static class EvenThread extends Thread {
    private String name;
    private AtomicInteger counter;

    public EvenThread(String name, AtomicInteger counter) {
        this.name = name;
        this.counter = counter;
    }

    public void run() {
        do {
            synchronized (counter) {
                if (counter.get() % 2 == 0) {
                    System.out.println("Thread is " + name + ", Counter is = " + counter.getAndAdd(1));
                    counter.notifyAll();
                } else {
                    try {
                        counter.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        } while (counter.get() <= 10);
    }
}

private static class OddThread extends Thread {
    private String name;
    private AtomicInteger counter;

    public OddThread(String name, AtomicInteger counter) {
        this.name = name;
        this.counter = counter;
    }

    public void run() {
        do {
            synchronized (counter) {
                if (counter.get() % 2 != 0) {
                    System.out.println("Thread is " + name + ", Counter is = " + counter.getAndAdd(1));
                    counter.notifyAll();
                } else {
                    try {
                        counter.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        } while (counter.get() <= 10);
    }
}

}

于 2013-11-18T11:18:17.980 回答
-1

您好,在这里您必须使用 java 同步。基本上同步是线程之间共享的Java机制,当一个线程正在运行时,它会阻塞所有其他线程。通过在您的情况下这样做,您可以按顺序打印它们。您可以阅读以下教程以了解它

http://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html http://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html

使用时要小心,因为不小心使用可能会造成死锁 http://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html

于 2013-06-08T14:18:22.883 回答
-2

您可以通过让线程获取公共锁以允许打印任何内容来实现此目的。

“锁”可能是一些单例,例如:

public class Lock {

private static Lock instance;
private static boolean inUse = false;

public static Lock getInstance() {
    if(instance == null) {
        instance = new Lock();
    }
    return instance;
}

public boolean acquireLock() {
    boolean rv = false;
    if(inUse == false) {
        inUse = true;
        rv = true;
    }
    return rv;
}

public void releaseLock() {
    inUse = false;
}

}

每当一个线程想要打印时,它必须调用acquireLock()它,如果它返回 true,那么它就可以打印。如果它返回假,那么它必须等到它返回真。在打印线程调用后立即releaseLock()释放锁。

我没有测试此代码,因此使用它需要您自担风险。我只是很快就输入了它,因为这是我正在考虑的想法。

您可以在此处阅读有关锁及其同步使用的更多信息:http://en.wikipedia.org/wiki/Lock_(computer_science)

于 2013-06-08T14:29:04.677 回答