Java多线程

Java多线程,java,multithreading,Java,Multithreading,我必须使用两个线程,一个线程打印所有小于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

我必须使用两个线程,一个线程打印所有小于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();
}
}
类printodd扩展线程{
公开募捐{
super.run();

对于(int i=0;iHi),在这里您必须使用java同步。基本上,同步是线程之间共享的java机制,它将在一个线程运行时阻止所有其他线程。在您的情况下,这样做可以按顺序打印它们。 您可以阅读以下教程来理解它

但是在使用时要小心,因为不小心使用可能会造成死锁

您可以通过让线程获得一个公共锁来实现这一点,以便允许打印任何内容

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

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,那么它可以打印。如果它返回false,那么它必须等待直到它返回true。打印后线程立即调用
releaseLock()
,以便释放锁

我没有测试这段代码,所以使用它的风险由你自己承担。我只是很快地把它打出来,因为这是我想到的想法

您可以在此处阅读有关锁及其在同步中的使用的更多信息:

试试这个

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
公共类顺序线程打印机{
公共静态void main(字符串[]args){
AtomicInteger计数器=新的AtomicInteger(0);
EvenThread偶数=新的EvenThread(“偶数”,计数器);
OddThread奇数=新的OddThread(“奇数”,计数器);
偶数。开始();
奇。开始();
}
}
私有静态类EvenThread扩展线程{
私有字符串名称;
专用原子整数计数器;
公共事件线程(字符串名称,原子整数计数器){
this.name=名称;
this.counter=计数器;
}
公开募捐{
做{
已同步(计数器){
if(counter.get()%2==0){
System.out.println(“线程为“+name+”,计数器为=“+Counter.getAndAdd(1));
counter.notifyAll();
}否则{
试一试{
counter.wait();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}

}while(counter.get()同步方法是什么意思?它们是两个独立的线程打印,为什么需要同步?即使同一对象的线程正在打印也没关系,但我希望线程轮流按1,2,3,4,5,6,7,8,9的顺序打印数字……还有其他方法可以实现吗?@greedybuddhaYou会想使用co两个类之间有一个布尔变量。然后,当它不是右转弯时,您将
等待
。当您完成后,您将
通知
,顺便说一句,由于您的
睡眠(1000)
睡眠(1050),您的代码将无法达到最大值(例如,打印所有小于10000的偶数/奇数)
。最好让
print偶数
线程
sleep(50)
在循环外部,然后在循环内部使用
sleep(1000)
,这样它们的频率相同但不同步。听起来像是一个家庭作业问题。获取锁不是线程安全的。只需急切地实例化它。谢谢…,;-)顺便说一句,这是在一次采访中被问到的….,听起来很有趣,所以我把它贴在这里….,:-)
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);
    }
}