Доступ к ограниченным по объему бобам прокси в Потоках

Лямбда, поднимающаяся, является техникой для 'снимания' лямбд к более высокому уровню (главным образом к верхнему уровню).

Doug Currie описывает, почему Вы хотели бы сделать это.

Вот некоторый пример кода (в JavaScript) того, как Вы могли сделать это вручную:

function addFive(nr)
{
  var x = 5;
  function addX(y)
  {
    return x + y;
  }

  return addX(nr);
}

Теперь, если Вы не хотите этот addX функция в определении addFive, Вы могли бы 'снять' его к верхнему уровню как так:

function addX(y)
{
  return x + y;
}

function addFive(nr)
{
  var x = 5;

  return addX(nr);
}

Однако это не будет работать, начиная с x переменная больше не доступна в контексте эти addX функция. Способ зафиксировать это состоит в том, чтобы добавить дополнительный формальный параметр к функции:

function addX(y, x)
{
  return x + y;
}

function addFive(nr)
{
  var x = 5;

  return addX(nr, x);
}
<час>

Дополнение: Вот является очень изобретенный пример лямбды 'выходом'. Где Вы не будете в состоянии сделать лямбду, поднимающуюся так же легко, как я описал.

function getAddFiveFunc()
{
  var x = 5;
  function addX(y)
  {
    return x + y;
  }

  return addX;
}

Теперь, если кто-то звонит эти getAddFiveFunc функция, они вернут функцию. Эта функция могла использоваться во всех видах мест, Теперь, если Вы действительно хотите подняться эти addX функция, необходимо будет обновить все те callsites.

16
задан Perulish8 6 October 2009 в 22:32
поделиться

3 ответа

Я использую следующий суперкласс для своих задач, которым необходим доступ к области запроса. По сути, вы можете просто расширить его и реализовать свою логику в методе onRun ().

import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

/**
 * @author Eugene Kuleshov
 */
public abstract class RequestAwareRunnable implements Runnable {
  private final RequestAttributes requestAttributes;
  private Thread thread;

  public RequestAwareRunnable() {
    this.requestAttributes = RequestContextHolder.getRequestAttributes();
    this.thread = Thread.currentThread();
  }

  public void run() {
    try {
      RequestContextHolder.setRequestAttributes(requestAttributes);
      onRun();
    } finally {
      if (Thread.currentThread() != thread) {
        RequestContextHolder.resetRequestAttributes();
      }
      thread = null;
    }
  }

  protected abstract void onRun();
}
47
ответ дан 30 November 2019 в 15:23
поделиться

Не могли бы вы попробовать наоборот? Используйте контейнер данных, который хранится в области запроса, и передайте его пулу потоков (возможно, поместите его в очередь, чтобы пул потоков мог принимать по одному контейнеру данных за раз, работать с ним, отмечать его как «выполненное» и продолжать со следующим).

0
ответ дан 30 November 2019 в 15:23
поделиться

Spring имеет класс ThreadPoolTaskExecutor , который можно использовать для управления пулом потоков из Spring. Однако похоже, что вам придется поработать, чтобы сделать контекст Spring доступным для каждого потока.

Я не уверен, что он будет работать, даже если вы подключите его таким образом. Spring использует токен в локальном потоке для поиска объектов в области запроса (или сеанса), поэтому, если вы пытаетесь получить доступ к bean-объекту области запроса из другого потока, вероятно, этого токена там не будет.

0
ответ дан 30 November 2019 в 15:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: