java - 如何正确同步两个线程
问题描述
这是我在学校里一直听说的一个问题,但在我被要求面试之前,我从来没有理由去解决这个问题。
提示:使用 2 个线程按顺序打印"Thread i: The number is 'j'"
,其中 j = 1:100,i 是线程数。线程 1 只能打印奇数 j,线程 2 只能打印偶数 j。
编辑j 的输出必须是有序的
这是我的尝试,但我没有在面试过程中继续前进。我缺少任何基本的部分吗?有什么优化吗?
import java.util.concurrent.Semaphore;
public class ThreadSynchronization implements Runnable {
private int start;
private Semaphore semaphore;
private ThreadSynchronization(int start, Semaphore semaphore) {
this.start = start;
this.semaphore = semaphore;
}
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(1, true);
semaphore.acquireUninterruptibly();
start(1, semaphore);
start(2, semaphore);
semaphore.release();
}
private static void start(int start, Semaphore semaphore) {
ThreadSynchronization ts = new ThreadSynchronization(start, semaphore);
Thread thread = new Thread(ts);
thread.start();
while (thread.getState() != Thread.State.WAITING) ;
}
@Override
public void run() {
for (int i = start; i <= 100; i += 2) {
semaphore.acquireUninterruptibly();
System.out.println("Thread " + start + ": The number is '" + i + "'");
semaphore.release();
}
}
}
解决方案
一个线程可以继续获取和释放Semaphore
,而另一个线程饿死。
你可以用wait
and来做到这一点notify
,试试这个:
import java.util.concurrent.atomic.AtomicInteger;
class Odd implements Runnable {
private AtomicInteger integer;
private final Object lock;
public Odd(AtomicInteger integer, Object lock) {
this.integer = integer;
this.lock = lock;
}
@Override
public void run() {
synchronized (lock) {
try {
while (integer.get() <= 100) {
while (integer.get() % 2 == 0) {
lock.notify();
lock.wait();
}
if (integer.get() <= 100) {
System.out.println("Thread " +
Thread.currentThread().getName() + ": The number is '" + integer.get() + "'");
}
integer.getAndIncrement();
lock.notify();
}
} catch (Exception e) {
}
}
}
}
class Even implements Runnable {
private AtomicInteger integer;
private final Object lock;
public Even(AtomicInteger integer, Object lock) {
this.integer = integer;
this.lock = lock;
}
@Override
public void run() {
synchronized (lock) {
try {
while (integer.get() <= 100) {
while (integer.get() % 2 != 0) {
lock.notify();
lock.wait();
}
if (integer.get() <= 100) {
System.out.println("Thread " +
Thread.currentThread().getName() + ": The number is '" + integer.get() + "'");
}
integer.getAndIncrement();
lock.notify();
}
} catch (Exception e) {
}
}
}
}
public class ThreadSynchronization {
public static void main(String[] args) throws Exception{
Object lock = new Object();
AtomicInteger integer = new AtomicInteger(1);
Odd odd = new Odd(integer, lock);
Even even = new Even(integer, lock);
Thread thread1 = new Thread(odd, "1");
Thread thread2 = new Thread(even, "2");
thread1.start();
thread2.start();
thread1.join();
thread2.join();
}
}
推荐阅读
- node.js - React.js 从本地文件读取
- javascript - 如何将光标放在 ExtJS 中 TextField 的末尾
- python-3.x - 当我导入 tensorflow 时,Tensorflow 在 AMD 上给出错误“/usr/lib/python3.6/importlib/_bootstrap.py:219: RuntimeWarning: compiletime....”
- c# - 从视图中设置数据绑定的背景
- javascript - 如何修复“错误:函数超时,确保承诺在 60000 毫秒内解决”
- javascript - 无法将正则表达式与 javascript 一起使用?
- javascript - 在输入值之前和之后动态添加文本而不修改值
- javascript - java - 如何使用java脚本中的一个函数使多个按钮独立工作?
- python - 如何在 QTest 中生成鼠标点击 QGraphicsWidget?
- jupyter-notebook - 如何将一组 Button 对象链接到图像输出以形成图像幻灯片?