Đây là biến thể trên CounterLatch
, có sẵn trên trang web Apache.
Phiên bản của chúng, vì những lý do được biết đến nhiều nhất, chặn chuỗi người gọi trong khi biến (AtomicInteger
) có giá trị nhất định.
Nhưng đó là chiều cao của sự yên tĩnh để tinh chỉnh mã này để bạn có thể chọn hoặc chỉ là phiên bản Apache, hoặc ... để nói "chờ ở đây cho đến khi bộ đếm đạt đến một giá trị nhất định". Có thể cho rằng sau này sẽ có nhiều ứng dụng hơn. Trong trường hợp cụ thể của tôi, tôi đã xáo trộn điều này bởi vì tôi muốn kiểm tra xem tất cả các "khối" đã được xuất bản trong SwingWorker.process()
... nhưng tôi đã tìm thấy các ứng dụng khác cho nó.
Ở đây nó được viết bằng Jython, chính thức là ngôn ngữ tốt nhất trên thế giới (TM). Tôi sẽ xáo trộn lên một phiên bản Java trong khóa học do.
class CounterLatch():
def __init__(self, initial = 0, wait_value = 0, lift_on_reached = True):
self.count = java.util.concurrent.atomic.AtomicLong(initial)
self.signal = java.util.concurrent.atomic.AtomicLong(wait_value)
class Sync(java.util.concurrent.locks.AbstractQueuedSynchronizer):
def tryAcquireShared(sync_self, arg):
if lift_on_reached:
return -1 if ((not self.released.get()) and self.count.get() != self.signal.get()) else 1
else:
return -1 if ((not self.released.get()) and self.count.get() == self.signal.get()) else 1
def tryReleaseShared(self, args):
return True
self.sync = Sync()
self.released = java.util.concurrent.atomic.AtomicBoolean() # initialised at False
def await(self, *args):
if args:
assert len(args) == 2
assert type(args[ 0 ]) is int
timeout = args[ 0 ]
assert type(args[ 1 ]) is java.util.concurrent.TimeUnit
unit = args[ 1 ]
return self.sync.tryAcquireSharedNanos(1, unit.toNanos(timeout))
else:
self.sync.acquireSharedInterruptibly(1)
def count_relative(self, n):
previous = self.count.addAndGet(n)
if previous == self.signal.get():
self.sync.releaseShared(0)
return previous
NB phiên bản Apache sử dụng từ khóa volatile
cho signal
và released
. Trong Jython tôi không nghĩ rằng điều này tồn tại như vậy, nhưng sử dụng AtomicInteger
và AtomicBoolean
phải đảm bảo rằng không có giá trị nào là "lỗi thời" trong bất kỳ chuỗi nào.
Ví dụ sử dụng:
Trong constructor SwingWorker:
self.publication_counter_latch = CounterLatch()
Trong SW.publish:
# increase counter value BEFORE publishing chunks
self.publication_counter_latch.count_relative(len(chunks))
self.super__publish(chunks)
Trong SW.process:
# ... do sthg [HERE] with the chunks!
# AFTER having done what you want to do with your chunks:
self.publication_counter_latch.count_relative(- len(chunks))
Trong thread đang đợi xử lý đoạn văn bản t o stop:
worker.publication_counter_latch.await()
Vâng, điều đó sẽ hiệu quả. Nhưng tôi muốn một cái gì đó mà không sử dụng 2 đối tượng đồng bộ hóa để đạt được điều này. Tôi đã thực hiện một bằng cách sử dụng LockSupport và hiện đang thử nghiệm nó để xem nếu nó hoạt động và thực hiện okay (AQS dường như không được tốt cho việc này hoặc là). – Razvi
@ dead10ck tại sao không? – assylias