为了账号安全,请及时绑定邮箱和手机立即绑定

FairSync能否保证执行顺序?

FairSync能否保证执行顺序?

翻阅古今 2023-07-19 15:48:33
我的第一个问题,谢谢您的帮助!我正在尝试使用两个线程交替打印奇数和偶数 1~100。预期成绩:    pool-1-thread-1=> 1    pool-1-thread-2=> 2    pool-1-thread-1=> 3    pool-1-thread-2=> 4    ......    pool-1-thread-1=> 99    pool-1-thread-2=> 100我想我可以使用FairSync,但它只能保证大部分打印是正确的。像这样:pool-1-thread-1=> 55pool-1-thread-2=> 56pool-1-thread-1=> 57pool-1-thread-2=> 58   pool-1-thread-2=> 59  //※error print※pool-1-thread-1=> 60pool-1-thread-2=> 61pool-1-thread-1=> 62不知道为什么极少数情况下订单会丢失?你可以批评我的代码和我的英语。这是我的代码:private static final int COUNT = 100;private static final int THREAD_COUNT = 2;private static int curr = 1;static ReentrantLock lock = new ReentrantLock(true);static ExecutorService executorService = Executors.newCachedThreadPool();public static void main(String[] args) {    Runnable task = () -> {        for (; ; ) {            try {                lock.lock();                if (curr <= COUNT) {                    System.out.println(Thread.currentThread().getName() + "=> " + curr++);                } else {                    System.exit(0);                }            } catch (Exception e) {                e.printStackTrace();            } finally {                lock.unlock();            }        }    };    for (int i = 0; i < THREAD_COUNT; i++) {        executorService.execute(task);    }}
查看完整描述

2 回答

?
蝴蝶刀刀

TA贡献1801条经验 获得超8个赞

不,亲爱的,你的实施不正确。哪个线程有机会运行是由操作系统决定的。无法保证线程 1 和 2 会相继执行。


您可以通过检查变量 curr 的先前值来修复代码,如果该值不是该线程期望的值,则不要增加并打印。


为我:


if(curr.threadName.equals("Thread 2") && (curr%2 !=0))

{

// Print

// Increment

}


查看完整回答
反对 回复 2023-07-19
?
千万里不及你

TA贡献1784条经验 获得超9个赞

您不能使用单锁来实现此目的。即使ReentrantLock提供公平性,但它无法控制线程调度。


我们可以实现像抛出一样的线程间通信Semaphore。信号量控制线程的执行。


我们创建两个线程,一个奇数线程和一个偶数线程。奇数线程将打印从 1 开始的奇数,偶数线程将打印从 2 开始的偶数。


创建两个信号量 semOdd 和 semEven,它们一开始有 1 和 0 许可。这将确保首先打印奇数。


class SharedPrinter {


    private Semaphore semEven = new Semaphore(0);

    private Semaphore semOdd = new Semaphore(1);


    void printEvenNum(int num) {

        try {

            semEven.acquire();

        } catch (InterruptedException e) {

            Thread.currentThread().interrupt();

        }

        System.out.println(Thread.currentThread().getName() + num);

        semOdd.release();

    }


    void printOddNum(int num) {

        try {

            semOdd.acquire();

        } catch (InterruptedException e) {

            Thread.currentThread().interrupt();

        }

        System.out.println(Thread.currentThread().getName() + num);

        semEven.release();


    }

}


class Even implements Runnable {

    private SharedPrinter sp;

    private int max;


    // standard constructor


    @Override

    public void run() {

        for (int i = 2; i <= max; i = i + 2) {

            sp.printEvenNum(i);

        }

    }

}


class Odd implements Runnable {

    private SharedPrinter sp;

    private int max;


    // standard constructors 

    @Override

    public void run() {

        for (int i = 1; i <= max; i = i + 2) {

            sp.printOddNum(i);

        }

    }

}


public static void main(String[] args) {

    SharedPrinter sp = new SharedPrinter();

    Thread odd = new Thread(new Odd(sp, 10),"Odd");

    Thread even = new Thread(new Even(sp, 10),"Even");

    odd.start();

    even.start();

}


查看完整回答
反对 回复 2023-07-19
  • 2 回答
  • 0 关注
  • 103 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信