• 解决共享资源竞争


    synchronized:

    public abstract class IntGenerator {
    private volatile boolean canceled = false;
    public abstract int next();
    // Allow this to be canceled:
    public void cancel() { canceled = true; }
    public boolean isCanceled() { return canceled; }
    } ///:~

    public class
    SynchronizedEvenGenerator extends IntGenerator {
    private int currentEvenValue = 0;
    public synchronized int next() {
    ++currentEvenValue;
    Thread.yield(); // Cause failure faster
    ++currentEvenValue;
    return currentEvenValue;
    }
    public static void main(String[] args) {
    EvenChecker.test(new SynchronizedEvenGenerator());
    }
    } ///:~

    public class EvenChecker implements Runnable {
    private IntGenerator generator;
    private final int id;
    public EvenChecker(IntGenerator g, int ident) {
    generator = g;
    id = ident;
    }
    public void run() {
    while(!generator.isCanceled()) {
    int val = generator.next();
    if(val % 2 != 0) {
    System.out.println(val + " not even!");
    generator.cancel(); // Cancels all EvenCheckers
    }
    }
    }
    // Test any type of IntGenerator:
    public static void test(IntGenerator gp, int count) {
    System.out.println("Press Control-C to exit");
    ExecutorService exec = Executors.newCachedThreadPool();
    for(int i = 0; i < count; i++)
    exec.execute(new EvenChecker(gp, i));
    exec.shutdown();
    }
    // Default value for count:
    public static void test(IntGenerator gp) {
    test(gp, 10);
    }
    } ///:~

    2.使用显示的Lock对象:

    MutexEvenGenerator 添加被互斥调用的锁:

    public class MutexEvenGenerator extends IntGenerator {
    private int currentEvenValue = 0;
    private Lock lock = new ReentrantLock();
    public int next() {
    lock.lock();
    try {
    ++currentEvenValue;
    Thread.yield(); // Cause failure faster
    ++currentEvenValue;
    return currentEvenValue;
    } finally {
    lock.unlock();
    }
    }
    public static void main(String[] args) {
    EvenChecker.test(new MutexEvenGenerator());
    }
    } ///:~

    使用Lock可以在异常抛出做finally清理工作,而synchronized不行。但用户用synchronized出现错误概率低,只有在解决特殊问题才用Lock(可以尝试获取锁,没有获取到可以做其他事情)

    public class AttemptLocking {
    private ReentrantLock lock = new ReentrantLock();

    public AttemptLocking(){
    System.out.println("xxxx");
    }
    public void untimed() {
    boolean captured = lock.tryLock();
    try {
    System.out.println("tryLock(): " + captured);
    } finally {
    if(captured)
    lock.unlock();
    }
    }
    public void timed() {
    boolean captured = false;
    try {
    captured = lock.tryLock(2, TimeUnit.SECONDS);
    } catch(InterruptedException e) {
    throw new RuntimeException(e);
    }
    try {
    System.out.println("tryLock(2, TimeUnit.SECONDS): " +
    captured);
    } finally {
    if(captured)
    lock.unlock();
    }
    }
    public static void main(String[] args) {
    final AttemptLocking al = new AttemptLocking();
    al.untimed(); // True -- lock is available
    al.timed(); // True -- lock is available
    // Now create a separate task to grab the lock:
    new Thread() {
    { setDaemon(true); }
    public void run() {
    al.lock.lock();
    System.out.println("acquired");
    }
    }.start();
    Thread.yield(); // Give the 2nd task a chance
    al.untimed(); // False -- lock grabbed by task
    al.timed(); // False -- lock grabbed by task
    }
    } /* Output:
    tryLock(): true
    tryLock(2, TimeUnit.SECONDS): true
    acquired
    tryLock(): false
    tryLock(2, TimeUnit.SECONDS): false
    *///:~

  • 相关阅读:
    9.2模拟题解
    NOI1995 石子合并
    NOIP2012 借教室
    织梦内页读取栏目banner图
    mysql数据库版本引发的问题
    简单修改hosts文件加快打开网页速度
    详细剖析电脑hosts文件的作用和修改
    内部标签样式
    织梦让当前的子栏目拥有特殊的样式
    织梦获取单个顶级栏目名
  • 原文地址:https://www.cnblogs.com/daxiong225/p/8975071.html
Copyright © 2020-2023  润新知