2014-11-29 2 views
0

Я пишу проект обработки (обработка основана на Java). Я хочу запустить код внутри одного потока в другом потоке (основной поток).Код запуска внутри одной темы в другой

//This method runs in the main thread 
public void draw() { 

} 

//This is a callback that runs in a separate thread 
void addTuioObject(TuioObject tobj) { 
    rect(0, 0, 20, 10); 
} 

rect(0,0,20,10) не запускается в главном потоке (предполагается нарисовать прямоугольник на экране). Полагаю, это потому, что он работает в отдельном потоке. Как я могу запустить этот код в основном потоке?

ответ

1

Наиболее распространенным решением является создание переменной состояния и сделать draw() способ сделать в соответствии с текущим состоянием .

Переменная состояния может быть такой же простой, как один примитивный тип (например, булев) или сложный объект.

Идея в том, что:

  • основной поток (поток анимации в обработке) вызывает draw() для каждый кадр и draw() метод использует переменную состояния, чтобы нарисовать экран.
  • другой поток может изменять состояние, но не имеет ничего общего с рисунком или пикселы ...

Рассмотрим 2 примера:

1) простое состояние (одна логическая переменная)

// state variable 
private boolean shouldPaint; 

void draw() { 
    background(0); 

    fill(200); 
    rect(10, 10, 30, 30); 

    if (shouldPaint) { 
     rect(50, 10, 30, 30); 
    } 
} 

// called in other thread 
someMethod() { 
    shouldPaint = !shouldPaint; 
} 

2) более сложное состояние

// state variable 
private PVector[] vectors = new PVector[5]; 
private int index = 0; 

void draw() { 
    background(0); 
    fill(200); 

    for (PVector v : vectors) { 
     if (v != null) { 
      rect(v.x, v.y, 10, 10); 
     } 
    } 

} 

// called by other thread 
void someMethod() { 
    if (index >= vectors.length) { 
     index = 0; 
    } 

    // vector for current index value 
    PVector v = vectors[index]; 

    if (v == null) { 
     vectors[index] = new PVector(index * 20, index * 20); 
    } else { 
     vectors[index].add(new PVector(30, 0)); 
    } 

    index++; 
} 

Напомним, что draw() метод вызывается 60 раз в секунду (если частота кадров по умолчанию). Каждое исполнение draw() изменяет буфер экрана (пикселя). Если вы хотите удалить ненужные объекты с экрана, вы должны запустить метод draw() с background(color), который очищает весь буфер.

0

Существует несколько способов сделать это. В зависимости от того, чего вы на самом деле хотите достичь. Если вы работаете с awt или качаете, код рисования должен фактически не запускаться в основном потоке, а в потоке awt. Вы можете отправить работу в этот поток, например, с помощью SwingUtils. Если вы действительно хотите выполнить код в другом потоке (например, main), вам нужно убедиться, что целевой поток сможет получить новую работу, например. из очереди.