java - 寻找更好的方式记录wait()和notify()方法

标签 java multithreading logging locking wrapper

每当尝试调用并返回Object类中的wait,notify和notifyAll方法时,我都试图打印到控制台。为此,我创建了一个包装器类,该包装器类代表锁定对象调用wait,notify和notifyAll方法。然后,我在包装器上使用这些方法,而不是使用wait,notify和notifyAll。这是我的最佳尝试,

线程一运行Runnable r1

Runnable r1 = new Runnable() {
    @Override
    public void run() {
        synchronized (lock) {
            try {
                // wait not wrapped in while loop for brevity.
                //lock.wait(); 
                lock.objWrapper.waitNew(); // Use the wrapper method instead of wait()
            } catch (InterruptedException e) {}
        }
    }
};

线程两次运行Runnable r2
Runnable r2 = new Runnable() {
    @Override
    public void run() {
        synchronized(lock) {
            //lock.notifyAll();
            lock.objWrapper.notifyAllNew(); // Use the wrapper method instead of notifyAll()
        }
    }
};

锁类定义为
public class Lock {
    ObjWrapper objWrapper = new ObjWrapper(this);
    // shared data here
}

Lock lock = new Lock();

包装器类定义为:
public class ObjWrapper {
    Object obj = null;

    ObjWrapper(Object obj) {
        System.out.println("New Object wrapper created: Thread: " + Thread.currentThread() + " at time: " + Instant.now());
        this.obj = obj;
    }

    public void waitNew() throws InterruptedException {
        System.out.println("Entering Object::wait: Thread: " + Thread.currentThread() + " at time: " + Instant.now());
        obj.wait();
        System.out.println("Exiting Object::wait: Thread: " + Thread.currentThread() + " at time: " + Instant.now());
    }

    public void notifyNew() {
        System.out.println("Entering Object::notify: Thread: " + Thread.currentThread() + " at time: " + Instant.now());
        obj.notify();
        System.out.println("Exiting Object::notify: Thread: " + Thread.currentThread() + " at time: " + Instant.now());
    }

    public void notifyAllNew() {
        System.out.println("Entering Object::notifyAll: Thread: " + Thread.currentThread() + " at time: " + Instant.now());
        obj.notifyAll();
        System.out.println("Exiting Object::notifyAll: Thread: " + Thread.currentThread() + " at time: " + Instant.now());
    }
}

最后,使用
    Thread t1 = new Thread(r1);
    t1.setName("Thread One");
    t1.start();

    Thread t2 = new Thread(r2);
    t2.setName("Thread Two");
    t2.start();

控制台上的输出,
New Object wrapper created: Thread: Thread[main,5,main] at time: 2017-03-19T22:48:28.771Z
Entering Object::wait: Thread: Thread[Thread One,5,main] at time: 2017-03-19T22:48:28.844Z
Entering Object::notifyAll: Thread: Thread[Thread Two,5,main] at time: 2017-03-19T22:48:31.845Z
Exiting Object::notifyAll: Thread: Thread[Thread Two,5,main] at time: 2017-03-19T22:48:31.845Z
Exiting Object::wait: Thread: Thread[Thread One,5,main] at time: 2017-03-19T22:48:31.845Z

我的问题是
  • 还有其他更好的方法吗?
  • 使用ObjWrapper时是否会折断任何边缘情况?

  • 编辑:
    我不是在寻找更好的方法来锁定对象。更好地记录wait()notify()notifyAll()方法的调用的更好方法。

    最佳答案

    关于问题1,我宁愿将ReentrantLockCondition子类化,然后重写signal和await方法,因为使用这种方法,您无论如何都失去了使用关键字sync方法的可能性。

    关于问题2,在这里我可以看到的主要优势是,您受intrinsic lock和内在条件队列的束缚。在我看来,一个很大的警告是,如果您希望使用ReentrantLock和/或Condition,那么您将不得不编写新的包装器(可能不是很简单),冒着引入更多复杂性和更多问题的风险。

    现在,您可能已经知道了,我宁愿坚持使用更高级别的API,例如锁存器,信号灯,屏障,ConcurrentCollection等,并尽可能远离低级线程管理,它往往很快就会变得棘手。

    关于java - 寻找更好的方式记录wait()和notify()方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42893389/

    相关文章:

    c# - 我可以使用 Json.net 在一次操作中将嵌套属性序列化到我的类吗?

    java - java中curl请求

    java - Camel 进程不会因为(不存在的)机上交换而关闭

    Java让线程返回一些东西给主线程

    python - 如何在记录列表和数组时插入换行符?

    logging - IIS 托管的 ASP.NET Core 应用程序中的控制台日志在哪里

    android - 我们如何在设备上为基于 phonegap 的 iOS 和 android 应用程序维护错误日志文件 (.txt)?

    java - 在运行时动态添加实体类

    java - 重复的条目:gms/auth/api/signin/internal/zzf.class

    multithreading - 在新线程(Rust)中从共享库执行异步函数