【问题标题】:Java basic synchronized threads [duplicate]Java基本同步线程[重复]
【发布时间】:2026-01-13 01:25:01
【问题描述】:

我正在学习 Java,但在同步方面遇到了麻烦。我想要打印来自许多 Java 线程的数字列表,并让每个线程按顺序运行。我在使用同步时遇到问题,因为我不太了解。能帮忙理解吗?

我希望输出看到这个,但有时线程顺序错误。我希望:

1-thread1
2-thread2
3-thread1
4-thread2
5-thread1
6-thread2
...
48-thread2
49-thread1

我的破密码:

public class ManyThreadsAdd {
    public static int index = 0;

    public static void main(String[] args) {
        ManyThreadsAdd myClass = new ManyThreadsAdd();
        Thread thread1 = new Thread(myClass.new RunnableClass());
        Thread thread2 = new Thread(myClass.new RunnableClass());

        thread1.start();
        thread2.start();
    }

    class RunnableClass implements Runnable {
        public synchronized void run() {
            while (index < 49) {
                try {
                    Thread.sleep(100);
                    System.out.println(index+"-" +Thread.currentThread());
                    index = index + 1;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

【问题讨论】:

  • 您必须在此处使用wait()notify()。您需要线程之间的某种通信来实现输出。
  • 是的,我尝试等待并通知但总是错误的异常。也许普通类使用等待和通知?
  • 您必须使用共享锁。请参阅*.com/q/6017281/217324 的已接受答案。投票关闭作为一个骗局,因为这是同样的问题。我试图为你挑选一个好的,但如果这不能解决你的问题,那么这个问题上还有很多其他问题有答案,谷歌搜索“java multithreading even odd site:*.com”。
  • 您说您想使用“许多”线程,但您的示例输出显示两个;您是在使用恰好两个线程还是任意数量的线程?您是否希望线程以 exact 循环方式执行,例如t1, t2, ..., tN, t1, t2, ..., tN?如果要协调任意数量的线程,解决方案会稍微复杂一些。

标签: java multithreading synchronized


【解决方案1】:

这取决于你想做什么。

交替打印顺序的一种简单方法是在同一个对象上同步,在这种情况下,您可以使用索引或任何其他对象。

public class ManyThreadsAdd {
    public static AtomicInteger index = new AtomicInteger(0);

    public static void main(String[] args) {
        ManyThreadsAdd myClass = new ManyThreadsAdd();
        Thread thread1 = new Thread(myClass.new RunnableClass());
        Thread thread2 = new Thread(myClass.new RunnableClass());

        thread1.start();
        thread2.start();
    }

    class RunnableClass implements Runnable {
        public void run(){
            synchronized(index){
                while(index.get() < 49){
                    try {
                      Thread.sleep(100);
                      System.out.println(index.get()+"-" +Thread.currentThread());
                      index.incrementAndGet();
                      index.notify();
                      index.wait();
                    } catch (InterruptedException e) {
                      e.printStackTrace();
                    }
                }
            }
        }
    }
}

【讨论】:

  • 这个我最了解。很容易看到 Atomic 递增,然后是 notify() 和 wait()。谢谢
【解决方案2】:

首先,多线程本质上是异步的,您无法指定这些线程的执行顺序。如果您想要如下所示的输出,请使用循环:

1-thread1
2-thread2
3-thread1
4-thread2
5-thread1
6-thread2
...
48-thread2
49-thread1

其次,在public synchronized void run() 中添加synchronized 关键字将一无所获。这只是意味着在任何时候,一次只有一个线程可以调用该方法。当您为每个线程构建新类时,这是没有意义的。

第三,如果您确实需要在线程之间进行同步,请使用一个队列,您可以向其中添加任务,并且您的线程一次读取一个。

【讨论】:

  • 你总是打开新的 RunnableClass 所以不会有同步。使其成为单例类。