Используя request.getSession () как объект блокировки?

Необходимо копаться в неуправляемом коде. Вот статический класс, который я использовал:

public static class Recycle
{
    private const int FO_DELETE = 3;
    private const int FOF_ALLOWUNDO = 0x40;
    private const int FOF_NOCONFIRMATION = 0x0010;

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 1)]
    public struct SHFILEOPSTRUCT
    {
        public IntPtr hwnd;
        [MarshalAs(UnmanagedType.U4)]
        public int wFunc;
        public string pFrom;
        public string pTo;
        public short fFlags;
        [MarshalAs(UnmanagedType.Bool)]
        public bool fAnyOperationsAborted;
        public IntPtr hNameMappings;
        public string lpszProgressTitle;
    }

    [DllImport("shell32.dll", CharSet = CharSet.Auto)]
    static extern int SHFileOperation(ref SHFILEOPSTRUCT FileOp);

    public static void DeleteFileOperation(string filePath)
    {
        SHFILEOPSTRUCT fileop = new SHFILEOPSTRUCT();
        fileop.wFunc = FO_DELETE;
        fileop.pFrom = filePath + '\0' + '\0';
        fileop.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION;

        SHFileOperation(ref fileop);
    }
}

Приложение:

  • Tsk tsk Jeff для "использования Microsoft. VisualBasic" в коде C#.
  • Tsk tsk MS для помещения всех положительных героев в пространстве имен VisualBasic.
11
задан MCS 30 November 2009 в 15:50
поделиться

5 ответов

Обычно не одобряется использование блокировки, которую вы не можете контролировать. Область блокировки должна быть как можно более жесткой, и поскольку сеанс является более или менее глобальным объектом, он не отвечает всем требованиям. Попробуйте использовать отдельную блокировку из пакета java.util.concurrent.locks и примените ее к своему классу.

5
ответ дан 3 December 2019 в 07:38
поделиться

I took a look at the article you posted. You could skip synchronizing all together and take the same approach that the author did by using compare-and-set to ensure that your data is correct:

ServletContext ctx = getServletConfig().getServletContext();
AtomicReference<TYPE> holder 
    = (AtomicReference<TYPE>) ctx.getAttribute(TEST_ATTR);
while (true) {
    TYPE oldVal = holder.get();
    TYPE newVal = computeNewVal(oldVal);
    if (holder.compareAndSet(oldVal, newVal))
        break;
} 

holder.compareAndSet(old, new) will return false if some other thread updated the value of "holder" since you last read it. holder.compareAndSet(,) is put in a while(true) loop so that if the value did change before you were able to write it then you get a chance to read the value again and re-try your write.

http://java.sun.com/javase/6/docs/api/java/util/concurrent/atomic/AtomicReference.html

3
ответ дан 3 December 2019 в 07:38
поделиться

The spec does not guarantee that this will help at all:

synchronized (session) {
  Object obj = session.getAttribute(TEST_ATTR);
  if (obj==null) {
    obj = new MyObject();
    session.setAttribute(obj);
  }
}

(It might work for specific implementations, but there are no guarantees that it will work in all containers.)

Servlet 2.5 MR6 says:

Multiple servlets executing request threads may have active access to the same session object at the same time. The container must ensure that manipulation of internal data structures representing the session attributes is performed in a threadsafe manner. The Developer has the responsibility for threadsafe access to the attribute objects themselves. This will protect the attribute collection inside the HttpSession object from concurrent access, eliminating the opportunity for an application to cause that collection to become corrupted.

Basically, the spec makes it your problem. Your solution will have to be tailored to your application design and deployment plan. I'm not sure that there is a global solution to the problem that will work in all cases; however, you may get a better answer if you are more specific about the architecture of your application and configuration of your application server.

2
ответ дан 3 December 2019 в 07:38
поделиться

В контексте сервлетов? Сервлеты могут быть распределены по нескольким процессам, поэтому у вас не всегда может быть один и тот же объект сеанса. Следствием этого является то, что контейнер сервлета может решить предоставить вам другой объект сеанса в том же процессе.

IIRC, Брайан Гетц написал интересную статью о сложности правильного выполнения операций с сеансами.

Мой совет: Держитесь подальше от сеансов как можно дольше и не блокируйте случайные объекты (используйте объект блокировки, не имеющий другой цели).

3
ответ дан 3 December 2019 в 07:38
поделиться

Ваш код не будет работать как минимум по двум причинам.

1) Если сеанс не существует, вы можете легко создать его дважды для одного и того же пользователя и иметь уродливое состояние гонки.

2) Если сеанс не является одним и тем же объектом в потоках, то он все равно не будет работать. Сеанс, вероятно, будет equals () тому же сеансу в другом потоке, но это не сработает.

1
ответ дан 3 December 2019 в 07:38
поделиться
Другие вопросы по тегам:

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