Internal exception java nio channels closedchannelexception - IT Справочник

IT Справочник
3 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд

Internal exception java nio channels closedchannelexception

Internal exception java nio channels closedchannelexception

The equals method implements an equivalence relation on non-null object references:

  • It is reflexive: for any non-null reference value x , x.equals(x) should return true .
  • It is symmetric: for any non-null reference values x and y , x.equals(y) should return true if and only if y.equals(x) returns true .
  • It is transitive: for any non-null reference values x , y , and z , if x.equals(y) returns true and y.equals(z) returns true , then x.equals(z) should return true .
  • It is consistent: for any non-null reference values x and y , multiple invocations of x.equals(y) consistently return true or consistently return false , provided no information used in equals comparisons on the objects is modified.
  • For any non-null reference value x , x.equals(null) should return false .

The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y , this method returns true if and only if x and y refer to the same object ( x == y has the value true ).

Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.

This implementation returns the cause that was supplied via one of the constructors requiring a Throwable, or that was set after creation with the method. While it is typically unnecessary to override this method, a subclass can override it to return a cause set by some other means. This is appropriate for a «legacy chained throwable» that predates the addition of chained exceptions to Throwable. Note that it is not necessary to override any of the PrintStackTrace methods, all of which invoke the getCause method to determine the cause of a throwable.

Some virtual machines may, under some circumstances, omit one or more stack frames from the stack trace. In the extreme case, a virtual machine that has no stack trace information concerning this throwable is permitted to return a zero-length array from this method. Generally speaking, the array returned by this method will contain one element for every frame that would be printed by printStackTrace.

The general contract of hashCode is:

  • Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
  • If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
  • It is not required that if two objects are unequal according to the method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.

As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the Java TM programming language.)

This method can be called at most once. It is generally called from within the constructor, or immediately after creating the throwable. If this throwable was created with or , this method cannot be called even once.

The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object. The awakened thread will compete in the usual manner with any other threads that might be actively competing to synchronize on this object; for example, the awakened thread enjoys no reliable privilege or disadvantage in being the next thread to lock this object.

This method should only be called by a thread that is the owner of this object’s monitor. A thread becomes the owner of the object’s monitor in one of three ways:

  • By executing a synchronized instance method of that object.
  • By executing the body of a synchronized statement that synchronizes on the object.
  • For objects of type Class, by executing a synchronized static method of that class.

Only one thread at a time can own an object’s monitor.

The awakened threads will not be able to proceed until the current thread relinquishes the lock on this object. The awakened threads will compete in the usual manner with any other threads that might be actively competing to synchronize on this object; for example, the awakened threads enjoy no reliable privilege or disadvantage in being the next thread to lock this object.

This method should only be called by a thread that is the owner of this object’s monitor. See the notify method for a description of the ways in which a thread can become the owner of a monitor.

The current thread must own this object’s monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object’s monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.

Читать еще:  Java util arraylist

As in the one argument version, interrupts and spurious wakeups are possible, and this method should always be used in a loop: This method should only be called by a thread that is the owner of this object’s monitor. See the notify method for a description of the ways in which a thread can become the owner of a monitor.

The current thread must own this object’s monitor.

This method causes the current thread (call it T ) to place itself in the wait set for this object and then to relinquish any and all synchronization claims on this object. Thread T becomes disabled for thread scheduling purposes and lies dormant until one of four things happens:

  • Some other thread invokes the notify method for this object and thread T happens to be arbitrarily chosen as the thread to be awakened.
  • Some other thread invokes the notifyAll method for this object.
  • Some other thread interrupts thread T .
  • The specified amount of real time has elapsed, more or less. If timeout is zero, however, then real time is not taken into consideration and the thread simply waits until notified.

The thread T is then removed from the wait set for this object and re-enabled for thread scheduling. It then competes in the usual manner with other threads for the right to synchronize on the object; once it has gained control of the object, all its synchronization claims on the object are restored to the status quo ante — that is, to the situation as of the time that the wait method was invoked. Thread T then returns from the invocation of the wait method. Thus, on return from the wait method, the synchronization state of the object and of thread T is exactly as it was when the wait method was invoked.

A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious wakeup. While this will rarely occur in practice, applications must guard against it by testing for the condition that should have caused the thread to be awakened, and continuing to wait if the condition is not satisfied. In other words, waits should always occur in loops, like this one: (For more information on this topic, see Section 3.2.3 in Doug Lea’s «Concurrent Programming in Java (Second Edition)» (Addison-Wesley, 2000), or Item 50 in Joshua Bloch’s «Effective Java Programming Language Guide» (Addison-Wesley, 2001).

If the current thread is interrupted by another thread while it is waiting, then an InterruptedException is thrown. This exception is not thrown until the lock status of this object has been restored as described above.

Note that the wait method, as it places the current thread into the wait set for this object, unlocks only this object; any other objects on which the current thread may be synchronized remain locked while the thread waits.

This method should only be called by a thread that is the owner of this object’s monitor. See the notify method for a description of the ways in which a thread can become the owner of a monitor.

Internal exception java nio channels closedchannelexception

Версия: 1.8.8, при заходе на сервер выдаёт следующие
lost connection: Internal Exception: io.netty.handler.codec.DecoderException: The received string length is longer than maximum allowed (22 > 16)

И ещё обнаружил то, что в папке с сервером есть файл hs_err_pid7616.log, если это имеет значение

#A fatal error has been detected by the Java Runtime Environment:
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x46bce470, pid=7616, tid=2432
# JRE version: Java(TM) SE Runtime Environment (8.0_65-b17) (build 1.8.0_65-b17)
# Java VM: Java HotSpot(TM) Client VM (25.65-b01 mixed mode windows-x86 )
# Problematic frame:
# C [awt.dll+0x1e470]
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
# If you would like to submit a bug report, please visit:
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.

Current thread (0x45c63400): JavaThread «AWT-Windows» daemon [_thread_in_native, id=2432, stack(0x46e60000,0x46eb0000)]

siginfo: ExceptionCode=0xc0000005, reading address 0x00000000

EAX=0x46eaf4f4, EBX=0x000000c0, ECX=0x0000007e, EDX=0x000000c0
ESP=0x46eaf4dc, EBP=0x00000000, ESI=0x45cedc90, EDI=0x00000000
EIP=0x46bce470, EFLAGS=0x00010216

Top of Stack: (sp=0x46eaf4dc)
0x46eaf4dc: 46eaf4f4 00001000 00000000 00000001
0x46eaf4ec: 45c63df0 0010000f 46c968ca 46bc558b
0x46eaf4fc: 00000000 00000000 45c63df0 46bc566a
0x46eaf50c: 00000000 45c63df0 00000001 46bc576e
0x46eaf51c: 45c63df0 46bc1d90 45c1e288 00000000
0x46eaf52c: 46bc83fa 00000001 46ca6104 00000000
0x46eaf53c: 45c1e288 46bc98f2 46ca60fc 46bc9aeb
0x46eaf54c: 46ca60fc 46c55e99 00000000 c69d455a

Instructions: (pc=0x46bce470)
0x46bce450: d8 53 1b c0 57 8b be 10 a0 00 00 25 00 f0 ff ff
0x46bce460: 05 00 20 00 00 50 c1 e2 05 8d 44 24 14 50 8b da
0x46bce470: 8b 17 53 c1 e1 05 51 8b 4a 2c 57 ff d1 33 ff 3b
0x46bce480: c7 0f 8c 8f 00 00 00 8b 56 04 8b 4c 24 10 c1 e2

Register to memory mapping:

EAX=0x46eaf4f4 is pointing into the stack for thread: 0x45c63400
EBX=0x000000c0 is an unknown value
ECX=0x0000007e is an unknown value
EDX=0x000000c0 is an unknown value
ESP=0x46eaf4dc is pointing into the stack for thread: 0x45c63400
EBP=0x00000000 is an unknown value
ESI=0x45cedc90 is an unknown value
EDI=0x00000000 is an unknown value

Ошибка Conection reset — как исправить

В этом примере мы поговорим о Это подкласс IOException, поэтому это проверенное исключение, которое сигнализирует о проблеме при попытке открыть или получить доступ к сокету.

Настоятельно рекомендуется использовать самый «определенный» класс исключений сокетов, который более точно определяет проблему. Стоит также отметить, что SocketException, выдаётся на экран с сообщением об ошибке, которое очень информативно описывает ситуацию, вызвавшую исключение.

Читать еще:  Java util stack

Простое клиент-серверное приложение

Чтобы продемонстрировать это исключение, я собираюсь позаимствовать некоторый код из клиент-серверного приложения, которое есть в Он состоит из 2 потоков.

  • Поток 1 — SimpleServer, открывает сокет на локальном компьютере через порт 3333. Потом он ожидает установления соединения. Если происходит соединение, он создает входной поток и считывает 1 текстовую строчку, от клиента, который был подключен.
  • Поток номер 2 — SimpleClient, подключается к сокету сервера, открытого SimpleServer. Он отправляет одну текстовую строчку.

Получается, что 2 потока будут в разных классах, запущенных двумя разными основными методами, чтобы вызвать исключение:

Как вы можете видеть, я поместил в SimpleClient 15-секундную задержку, прежде чем попытаться отправить свое сообщение. К тому моменту, когда клиент вызывает sleep(), он уже создал соединение с сервером. Я собираюсь запустить оба потока, и после того, как клиент установит соединение, я внезапно остановлю клиентское приложение.
Вот что происходит на стороне сервера:

Мы получаем исключение SocketException с сообщением «Сброс подключения». Это происходит, когда один из участников принудительно закрывает соединение без использования close().

Конечно, вы можете сделать оперативное закрытие соединения, не закрывая приложение вручную. В коде клиента, после ожидания в течение 15 секунд (или меньше), вы можете выдать новое исключение (используя throws new Exception ()), но вы должны удалить finally, иначе соединение будет нормально закрываться, и SocketException не будет сброшен.

Как решить проблему с SocketException

SocketException — это общее исключение, обозначающее проблему при попытке доступа или открытия Socket. Решение этой проблемы должно быть сделано с особой тщательностью. Вы должны всегда регистрировать сообщение об ошибке, которое сопровождает исключение.

В предыдущем примере мы видели код сообщения. Это происходит, когда один из участников принудительно закрывает соединение без использования close (). Это означает, что вы должны проверить, был ли один из участников неожиданно прерван.

Также может быть сообщение «Слишком много открытых файлов», особенно если вы работаете в Linux. Это сообщение обозначает, что многие файловые дескрипторы открыты для системы. Вы можете избежать этой ошибки, если перейдете в /etc/sysctl.conf и увеличите число в поле fs.file-max. Или попытаться выделить больше стековой памяти.

Конечно, можно встретить много других сообщений. Например, «Ошибка привязки», где ваше соединение не может быть установлено, поскольку порт не может быть привязан к сокету. В этом случае проверьте, используется ли порт и т. д.
Если у вас проблема с minecraft, то в видео ниже очень просто объясняется как это решить.

Средняя оценка / 5. Количество голосов:

Спасибо, помогите другим — напишите комментарий, добавьте информации к статье.

Или поделись статьей

Видим, что вы не нашли ответ на свой вопрос.

Есть ли способ предотвратить ClosedByInterruptException?

В следующем примере у меня есть один файл, который используется двумя потоками (в реальном примере у меня может быть любое количество потоков)

Скорее создавая RandomAccessFile и сопоставление памяти для каждого потока, у меня есть один файл и одно сопоставление памяти, разделяемое между потоками, но есть catch, если какой-либо поток прерывается, ресурс закрывается.

Есть ли способ предотвратить блокировку FileChannel только потому, что один поток, использующий его, был прерван?

EDIT Что я хочу избежать, так это, как я подозреваю, это не сработает для Java 9+

BTW Вызов fc.size() возвращает размер, как ожидалось, с помощью вышеупомянутого взлома.

java interrupt java-9 filechannel

3 ответа

12 Решение Holger [2018-09-13 20:13:00]

Поскольку вы сказали, что хотите «одно сопоставление памяти, разделяемое между потоками», такой проблемы вообще нет, так как отображение памяти не влияет на закрытие FileChannel . Фактически, это хорошая стратегия как можно скорее закрыть канал, чтобы уменьшить ресурсы, удерживаемые приложением.

Это демонстрирует, как потоки могут читать и записывать свои данные после закрытия канала, а прерывание потока записи не останавливает поток чтения.

Если вам необходимо выполнить операции FileChannel в дополнение к I/O с отображением памяти, нет проблем с использованием нескольких экземпляров FileChannel , поэтому закрытие одного канала не влияет на другое. Например

Здесь прерывание одного потока закрывает его канал, но не влияет на другое. Кроме того, даже когда каждый поток получает свой собственный MappedByteBuffer из своего собственного канала, изменения просматриваются другим, даже без использования force() . Конечно, последнее определяется как зависящее от системы поведение, не гарантированное работать на каждой системе.

Но, как показано в первом примере, вы все равно можете создавать общие буферы только из одного из каналов в начале, одновременно выполняя операции ввода-вывода на другом канале, по одному на поток, и не имеет значения, будут ли и какие каналы закрыты, на него не влияют отображенные буферы.

Вы можете использовать отражение для доступа к interruptor поля и незаконно получить типа класса оттуда, чтобы создать экземпляр прокси:

В Java9 это работает с одним предупреждением, так как оно выполняется по умолчанию с —illegal-access=permit .

Однако этот флаг может быть удален в будущих версиях, и наилучшим способом обеспечения этого долгосрочного действия является использование флага —add-opens :

Или, если вы не работаете с модулями (не рекомендуется):

Это работает с Java 9, Java 10 и текущей версией JDK 11 Early-Access Build (28 (2018/8/23)).

7 Mumrah81 [2018-09-11 17:09:00]

Используя AsynchronousFileChannel, ClosedByInterruptException никогда не бросается. Кажется, что это не похоже на прерывание

Тест, выполненный с использованием jdk 1.8.0_72

Java Channels Tutorial – NIO 2.0

By Lokesh Gupta | Filed Under: Java New IO

Channels are the second major innovation of java.nio after buffers which we have learned in my previous tutorial in detail. Channels provide direct connections to I/O services. A Channel is a medium that transports data efficiently between byte buffers and the entity on the other end of the channel (usually a file or socket). Usually channels have a one-to-one relationship with operating-system file descriptors. The channel classes provide the abstraction needed to maintain platform independence but still model the native I/O capabilities of modern operating systems. Channels are gateways through which the native I/O services of the operating system can be accessed with a minimum of overhead, and buffers are the internal endpoints used by channels to send and receive data.

Читать еще:  Как открыть файл через java

NIO Channel Basics

At the top of hirarchy, there is Channel interface which looks like this:

Channel implementations vary radically between operating systems due to various factors which depend on underlying platform, so the channel APIs (or interfaces) simply describe what can be done. Channel implementations often use native code to perform actual work. In this way, the channel interfaces allow you to gain access to low-level I/O services in a controlled and portable way.

As you can see by the top-level Channel interface, there are only two operations common to all channels: checking to see if a channel is open ( isOpen() ) and closing an open channel ( close() ).

Opening Channels

As we already know that I/O falls into two broad categories: file I/O and stream I/O. So it’s no surprise that there are two types of channels: file and socket. FileChannel class and SocketChannel classes are used to deal with these two categories.

FileChannel object can be obtained only by calling the getChannel() method on an open RandomAccessFile , FileInputStream , or FileOutputStream object. You cannot create a FileChannel object directly.

Opposite to FileChannels, socket channels have factory methods to create new socket channels directly. e.g.

Above methods return a corresponding socket channel object. They are not sources of new channels as RandomAccessFile.getChannel() is. They return the channel associated with a socket if one already exists; they never create new channels.

Using Channels

As we already learned into buffers tutorial that channels transfer data to and from ByteBuffer objects. Most of the read/write operations are performed by methods implemented from below interfaces.

Channels can be unidirectional or bidirectional. A given channel class might implement ReadableByteChannel , which defines the read() method. Another might implement WritableByteChannel to provide write() . A class implementing one or the other of these interfaces is unidirectional: it can transfer data in only one direction. If a class implements both interfaces (or ByteChannel which extends both interfaces), it is bidirectional and can transfer data in both directions.

If you go through channel classes, you’ll find that each of the file and socket channels implement all three of these interfaces. In terms of class definition, this means that all file and socket channel objects are bidirectional. This is not a problem for sockets because they’re always bidirectional, but it is an issue for files. A FileChannel object obtained from the getChannel() method of a FileInputStream object is read-only but is bidirectional in terms of interface declarations because FileChannel implements ByteChannel . Invoking write() on such a channel will throw the unchecked NonWritableChannelException because FileInputStream always opens files with read-only permission. So keep remember that when a channel connects to a specific I/O service, and the capabilities of a channel instance will be constrained by the characteristics of the service to which it’s connected. A Channel instance connected to a read-only file cannot write, even though the class to which that channel instance belongs may have a write() method. It falls to the programmer to know how the channel was opened and not to attempt an operation the underlying I/O service won’t allow.

The read() and write() methods of ByteChannel take ByteBuffer objects as arguments. Each returns the number of bytes transferred, which can be less than the number of bytes in the buffer, or even zero. The position of the buffer will have been advanced by the same amount. If a partial transfer was performed, the buffer can be resubmitted to the channel to continue transferring data where it left off. Repeat until the buffer’s hasRemaining() method returns false.

In below example, we are copying data from one channel to another channel (or from one file to another file):

Channels can operate in blocking or non-blocking modes. A channel in non-blocking mode never puts the invoking thread to sleep. The requested operation either completes immediately or returns a result indicating that nothing was done. Only stream-oriented channels, such as sockets and pipes, can be placed in non-blocking mode.

Closing Channels

To close a channel, use it’s close() method. Unlike buffers, channels cannot be reused after closing it. An open channel represents a specific connection to a specific I/O service and encapsulates the state of that connection. When a channel is closed, that connection is lost, and the channel is no longer connected to anything.

It’s harmless to call close( ) on a channel multiple times. Subsequent calls to close( ) on the closed channel do nothing and return immediately.

The open state of a channel can be tested with the isOpen() method. If it returns true, the channel can be used. If false, the channel has been closed and can no longer be used. Attempting to read, write, or perform any other operation that requires the channel to be in an open state will result in a ClosedChannelException .

Ссылка на основную публикацию
ВсеИнструменты 220 Вольт