使用Java中的两个线程打印1-20号

问题描述 投票:1回答:4

我试图用两个线程打印数字1-20:

  • 连线程 - 仅打印偶数。
  • 奇数线程 - 仅打印奇数。

我还有一个用于同步的锁定对象。

我的申请被卡住了。你能告诉我这是什么问题吗?

我的代码:

public class runIt
{

    public static void main(String[] args)
    {
        Odd odd = new Odd("odd thread");
        Even even = new Even("even thread");

        odd._t.start();
        even._t.start();

        try{
            odd._t.join();
            even._t.join();
        }
        catch (InterruptedException e){
            System.out.println(e.getMessage());
        }   
    }
}

public class Constants{
    static Object lock = new Object();
}

public class Even implements Runnable{
    Thread  _t;
    String  _threadName;

    public Even(String threadName){
        _threadName = threadName;
        _t = new Thread(this);
    }

    @Override
    public void run(){
        for (int i = 0; i < 20; i++){
            if (i % 2 == 0){
                synchronized (Constants.lock){                  
                    try{
                        Constants.lock.wait();
                        Constants.lock.notifyAll();
                    }
                    catch (InterruptedException e){
                        e.printStackTrace();
                    }
                    System.out.println(_threadName + " " + i + " ");
                }
            }
        }
    }
}

public class Odd implements Runnable{
    Thread  _t;
    String  _threadName;

    public Odd(String threadName){
        _threadName = threadName;
        _t = new Thread(this);

    }

    @Override
    public void run(){
        for (int i = 0; i < 20; i++){
            if (i % 2 == 1){
                synchronized (Constants.lock){                  
                    try{
                        Constants.lock.wait();
                        Constants.lock.notifyAll();
                    }
                    catch (InterruptedException e1){
                        e1.printStackTrace();
                    }
                    System.out.println(_threadName + " " + i + " ");
                }
            }
        }
    }
}

我的输出应该是:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

谢谢你的帮助,谭。

java multithreading thread-safety deadlock thread-synchronization
4个回答
1
投票

您正在通过在synchronized中使用的对象上调用wait来滥用waitsynchronized,而没有在循环中同步块内部进行检查。永远不要再这样做了。

事实上,这是发生的事情:

  • synchronized线你可以锁定Constants.lock
  • wait行,您释放Constants.lock上的锁并等待来自另一个线程的通知。

那么你的编程发生了什么:

  • 第一个线程(无论它是什么)到达synchronized并继续阻止第二个
  • 第一个线程释放同步锁并使自己处于等待状态以进行通知
  • 第二个线程通过synchronized,因为第一个已释放锁定
  • 两个线程现在都在等待永远不会发生的通知

0
投票

下面的代码将有助于某人,

public class MyClass {

private static Object lock = new Object();

public static void main(String args[]){

    Runnable runnable1 = new Runnable() {
        @Override
        public void run() {
            for(int i=1; i<20; i=i+2){
                synchronized (lock) {
                    System.out.println("Thread 1: "+i);
                    try {
                        lock.notifyAll();
                        lock.wait();
                    } catch (InterruptedException e) {
                        System.out.println("Error in Thread 1: "+e.getMessage());
                    }
                }
            }
        }
    };


    Runnable runnable2 = new Runnable() {
        @Override
        public void run() {
            for(int i=2; i<=20; i=i+2){
                synchronized (lock) {
                    System.out.println("Thread 2: "+i);
                    try {
                        lock.notifyAll();
                        lock.wait();
                    } catch (InterruptedException e) {
                        System.out.println("Error in Thread 2: "+e.getMessage());
                    }
                }
            }
        }
    };

    Thread thread1 = new Thread(runnable1);
    Thread thread2 = new Thread(runnable2);

    System.out.println("Thread Start: ");
    thread1.start();
    thread2.start();               
}

}

0
投票

您可以在包声明中提到的站点中找到解释:这是工作代码:

public class MultipleThreading {
    int count = 1;
    int MAX = 20;

    public void printOdd() {
    synchronized (this) {
        while (count < MAX) {
        while (count % 2 == 0) {
            try {
            wait();
            } catch (InterruptedException e) {
            e.printStackTrace();
            }
        }
        System.out.print(count + " ");
        count++;
        notify();
        }
    }
    }

    public void printEven() {
    synchronized (this) {
        while (count < MAX) {
        while (count % 2 == 1) {
            try {
            wait();
            } catch (InterruptedException e) {
            e.printStackTrace();
            }
        }
        System.out.print(count + " ");
        count++;
        notify();
        }
    }
    }

    public static void main(String[] args) {
    MultipleThreading mt = new MultipleThreading();
    Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
        mt.printEven();
        }
    });
    Thread t2 = new Thread(new Runnable() {
        @Override
        public void run() {
        mt.printOdd();
        }
    });
    t1.start();
    t2.start();
    }
}

0
投票

Stack Overflow上的每个人都尝试了相同的解决方案。检查相同的不同实现。

public class PrintSequenceUsingTwo {

    public static void main(String[] args) {
        ThreadSequence sequence = new ThreadSequence();
        Thread t1 = new Thread(()-> {try {
            sequence.print();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }},"t1");
        Thread t2 = new Thread(()-> {try {
            sequence.print();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }},"t2");

        t1.start();
        t2.start();
        try {
            t1.join();
            t2.join();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class ThreadSequence {

    private static int var = 0; 
    private int limit = 10;     //set the variable value upto which you want to print

    public synchronized void print() throws InterruptedException {
        while (var<limit) {
            notify();
            System.out.println("Current Thread "+Thread.currentThread().getName()+" Value : "+(++var));
            wait();
        }
        notify();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.