Я использую java.util.concurrent. CountDownLatch для достижения цели.
Прежде всего я сделал интерфейс для каждой задачи.
interface GroupTask {
void onProcessing(final CountDownLatch latch);
}
Затем я создаю класс для обработки групповых задач.
interface MyDisptchGroupObserver {
void onAllGroupTaskFinish();
}
class MyDisptchGroup {
private static final int MSG_ALLTASKCOMPLETED = 300;
private CountDownLatch latch;
private MyDisptchGroupObserver observer;
private MsgHandler msgHandler;
private class MsgHandler extends Handler {
MsgHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
switch(msg.what) {
case MSG_ALLTASKCOMPLETED:
observer.onAllGroupTaskFinish();
break;
default:
break;
}
}
}
MyDisptchGroup(List<GroupTask> tasks, MyDisptchGroupObserver obj) {
latch = new CountDownLatch(tasks.size());
observer = obj;
msgHandler = new MsgHandler(getActivity().getMainLooper())
new Thread( new Runnable() {
@Override
public void run() {
try {
latch.await();
Log.d(TAG, "========= All Tasks Completed =========");
msgHandler.sendEmptyMessage(MSG_ALLTASKCOMPLETED);
} catch() {
e.printStackTrace();
}
}
}).start();
for( GroupTask task : tasks ) {
task.onProcessing(latch);
}
}
}
Конечно, у меня есть более одной реализации задачи, как показано ниже. Задача1
class Task1 implements GroupTask {
@Override
public void onProcessing(final CountDownLatch latch) {
new Thread( new Runnable() {
@Override
public void run() {
// Just implement my task1 stuff here
// The end of the Task1 remember to countDown
latch.countDown();
}
}).start();
}
}
И Задача2
class Task2 implements GroupTask {
@Override
public void onProcessing(final CountDownLatch latch) {
new Thread( new Runnable() {
@Override
public void run() {
// Just implement my task2 stuff here
// The end of the Task2 remember to countDown
latch.countDown();
}
}).start();
}
}
Теперь все готовы к стрельбе.
ArrayList<GroupTask> allTasks = new ArrayList<GroupTask>();
allTasks.add(new Task1());
allTasks.add(new Task2());
new MyDisptchGroup(allTasks, this);
Все функции также являются дескрипторами , поэтому вы можете связать их, вызвав их метод __ get __
:
bound_handler = handler.__get__(self, MyWidget)
Вот отличный Р. Хеттингер направляйте к дескрипторам.
В качестве автономного примера, взятого из Кита комментария :
def bind(instance, func, as_name=None):
"""
Bind the function *func* to *instance*, with either provided name *as_name*
or the existing name of *func*. The provided *func* should accept the
instance as the first argument, i.e. "self".
"""
if as_name is None:
as_name = func.__name__
bound_method = func.__get__(instance, instance.__class__)
setattr(instance, as_name, bound_method)
return bound_method
class Thing:
def __init__(self, val):
self.val = val
something = Thing(21)
def double(self):
return 2 * self.val
bind(something, double)
something.double() # returns 42
Это можно сделать чисто с помощью types.MethodType . Пример:
import types
def f(self): print self
class C(object): pass
meth = types.MethodType(f, C(), C) # Bind f to an instance of C
print meth # prints <bound method C.f of <__main__.C object at 0x01255E90>>
Это свяжет self
с обработчиком
:
bound_handler = lambda *args, **kwargs: handler(self, *args, **kwargs)
Это работает путем передачи self
в качестве первого аргумента функции . object.function ()
- это просто синтаксический сахар для функции (объекта)
.