搶購 庫存扣減

MaxKing發表於2022-01-17
#![allow(dead_code, unused_imports)]


use std::{sync::{atomic::{Ordering, AtomicU64}, Arc}, thread};
#[derive(Debug)]
struct Data{
    num: AtomicU64
}


impl Data {
    fn new(num: u64)-> Self{
        Data{
            num: AtomicU64::new(num)
        }
    }

    /**
     * num: 扣減數量
     * conn:原子操作重試次數
     */
    fn deductions(&self, num: u64, conn: u8) -> Result<u64,u64>{
        let mut old = self.num.load(Ordering::SeqCst);
        for _ in 0..conn{
            if num > old{
                return Err(old);
            }else{
                let now = old - num;
                let a= self.num.compare_exchange_weak(old, now, Ordering::SeqCst, Ordering::SeqCst);
                if a.is_ok(){
                    return a;
                }
                thread::yield_now();
                old = self.num.load(Ordering::SeqCst);
            }
        };
        Err(old)

    }
}

#[test]
#[allow(unused_must_use, unused_variables)]
fn test(){
    let  d = Arc::new(Data::new(5000));
    let t1 = Arc::clone(&d);
    let t1 = thread::spawn(move ||{
        for _ in 0..1000{
            let a= t1.deductions(1, 1);
            if let Err(num) = a{
                println!("Thread-1: {:?}", a);
            }
        }
    });
    let t2 = Arc::clone(&d);
    let t2 = thread::spawn(move ||{
        for _ in 0..1000{
            let a= t2.deductions(1, 2);
            if let Err(num) = a{
                println!("Thread-2: {:?}", a);
            }
        }
    });

    let t3 = Arc::clone(&d);
    let t3 = thread::spawn(move ||{
        for _ in 0..1000{
            let a= t3.deductions(1, 3);
            if let Err(num) = a{
                println!("Thread-3: {:?}", a);
            }
        }
    });

    t1.join(); t2.join(); t3.join();
    println!("{:?}",d)
}


本作品採用《CC 協議》,轉載必須註明作者和本文連結
謎麟

相關文章