Я пишу приложение, которое рисует определенные фигуры.
Прежде чем рисовать каждую фигуру, необходимо выполнить некоторые вычисления.Вот почему у меня есть еще один поток для рисования уже обработанных элементов.
Для синхронизации между двумя потоками я использовал семафор.Прежде чем ящик попытается извлечь элемент из очереди, он получит разрешение, и каждый раз, когда элемент ставится в очередь, он будет выдавать разрешение.Кроме того, методы enqueue
и dequeue
синхронизированы.вычислительная нить будет ждать окончания работы выдвижного ящика, если количество разрешений не равно нулю к моменту выполнения вычислительной нити.
РЕДАКТИРОВАТЬ Синхронизированный блок в вычислительной нити долженне допускать продолжения вычислительной нити до завершения рисования.Если бы это произошло, это могло бы испортить ситуацию.
После профилирования выдача разрешений занимает 8.3%
времени выполнения вычислительного потока.Что приемлемо.Проблема с рисунком темы.Метод получения занимает 63% времени выполнения.
Кроме того, я попытался использовать очередь блокировки, но это было еще хуже.
код:
поток рисования:
private void drawNext(){
QueuedDraw item;
if(drawingStatus.availablePermits()==0)
synchronized(drawingStatus){
if(drawingStatus.availablePermits()==0)
drawingStatus.notify();
}
try {
drawingStatus.acquire();
} catch (InterruptedException ex) {
Logger.getLogger(PolygonDrawer.class.getName())
.log(Level.SEVERE, null, ex);
}
item = queue.dequeue();
fillPoly(item.points, item.color, item.vertices);
}
public final void fillSquare(Point[] points, byte[] color){
queue.enqueue(new QueuedDraw(points, color, SQUARE_VERTICES));
drawingStatus.release();
}
public final void fillTriangle(Point[] points, byte[] color){
queue.enqueue(new QueuedDraw(points, color, TRIANGLE_VERTICES));
drawingStatus.release();
}
@Override
public void run() {
while(true){
drawNext();
}
}
поток вычислений:
примечание: перед этим блоком находятся все вызовы методов, которые вызывают fillSquare /fillTriangle
if(paintStatus.availablePermits()!=0)
synchronized(paintStatus){
try {
if(paintStatus.availablePermits()!=0)
paintStatus.wait();
} catch (InterruptedException ex) {
Logger.getLogger(Painter.class.getName())
.log(Level.SEVERE, null, ex);
}
}