Unconsciously has written to the fourth article, the third one is about the reflection mechanism set frame and so on, this time to talk about their own anti-serialization and multi-threaded understanding. Hope to be able to help you learn Java :
1. About serialization and deserialization
It should probably be known that the meaning of serialization and deserialization in Java, serialization is to convert a Java object into binary for the transmission of disk or network flow, deserialization means to re-assemble this received binary stream into the original object inverse process. They are implemented in Java by the two classes of ObjectInputStream and ObjectInputStream (hereinafter referred to as OIS and Oos respectively).
The Oos WriteObject () method is used to perform the serialization process, and Ois's ReadObject () is used to perform the deserialization process, which needs to be said to connect the two high-level stream objects to the same channel before transmitting the binary stream, which can be a disk file , or it can be the bottom stream of the socket. So either way, the underlying stream object is passed into the two high-level streams of the Oos and ois in the form of constructor arguments, and the connection is complete before the binary data transfer can be made. Example:
Can be a file flow channel:
- File = new file ("C:/data.dat");
- Oos = new objectoutputstream (new fileoutputstream (file));
- OIS = new objectinputstream (new fileinputstream (file));
|
or network circulation Channel:
- Oos = new ObjectOutputStream (Socket.getoutputstream ());
- OIS = new ObjectInputStream (Socket.getinputstream ());
|
Do not know whether people notice that the oos is always defined before ois, here do not want you to misunderstand this order is fixed? The answer is no, so is there a sequential requirement? The answer is yes. What is the principle?
The principle is that the input/output stream between the interfaces must be initialized before the output stream is initialized and then the input stream initializes, otherwise it throws an exception. You're sure to ask why? As long as you take a look at the source code files of these two classes, you probably know that the task of the output stream is simple, as long as the object is converted into a binary to write to the channel, but the input stream needs to do a lot of preparation to accept and eventually reorganize this object, Therefore, the ObjectInputStream constructor needs to use the output initialization sent over the header information, this method is called Readstreamheader (), It will read two short values to decide how much cache to use to store the binary stream sent by the channel, the size of this cache is different from the version of the JRE. So if output is not initialized first, the constructor of input will not run correctly first.
For the above two examples, the first order is strict, the second because the Oos and OIS connection is not the other side, but the other end of the socket flow, the need to strictly follow the other side of the output stream docking before the input stream open to smooth operation.
This writeobject and readobject are thread-safe in themselves and are not allowed to be accessed concurrently during transmission. So the object can be one after another, there are a lot of people in the run will encounter Eofexception, and then baffled, to various forums to ask the solution. In fact, I would like to say that this exception is not required to declare, that is, although it is abnormal, but in fact, the end of the normal operation of the flag. EOF means that the end of the file is read, and the outgoing connection is disconnected. If this affects the correctness of your program, please calm down and look at the business logic of your program, rather than concentrating on the methods of sending and receiving. Because the author is also plagued by such a bug for 1 of the day, many forum posts misunderstood a lot of the last lesson. If you go to ReadObject in the while loop, there is no problem at all, and the object data will be read, not automatically blocked. Then throw eofexception must be because the connection is broken still continue to read, what causes the connection broken? Must be the business logic where there are errors, such as Nullpoint, Classcaseexception, Arrayoutofbound, even if the program is large, it does not matter, at most as long as a single pace to find a bug and solve it quickly.
No wonder a program guru said: Problem solving 90% by experience, 5% by technology, and 5% by luck! Really good advice, I have probably consulted more than 30 discussions in the while loop using ReadObject thrown Eofexceptionde posts, everyone is blindly concerned about the interpretation of the noun, deserialization behavior or against this writing and no one thinks that EOF is the correct behavior, It is actually very honest in doing it thing. Why is everyone ignoring the real wrong place? Two words, experience!
2. Multithreaded Programming for Java
About Java threads, beginners or contact may also know some basic concepts, but also confused about the thread in the end what is going on? If someone thinks they already understand, answer the following question:
A. A object implements the Runnable interface, A.start () runs after the so-called thread object is who? Is it a?
B. When does the Wait (), notify () method of the thread be used, and when?
C. Why does the thread's suspend method be labeled obsolete, deprecated, and thread suspended?
D. In order to synchronize we will lock the thread method declaration synchronized to the object, then if the parent class F () method adds synchronized, the subclass rewrite F () method must also add synchronized? If the subclass's F () method overrides the declaration of synchronized and calls Super.f (), how many locks are there on the child class object? Will it cause a deadlock in the competition?
Hehe, can you answer up a few way? If these can be answered, the concept of thread is still full of clarity, although it is far from being proficient. The author here to answer, due to the reasons for the length, I try to say a little bit, if you have doubts about the welcome to discuss together.
First 1th, threads are completely different from objects, although we often talk about threading objects. But when you start a thread with Run () and start (), the thread is no longer related to the object that inherits the thread or implements the Runnable, and the object can only count the available resources in memory and the object's method can only count the code snippets that the memory body area could execute. Since it is a resource and a code snippet, the other thread can also access, the main function executes at least two threads, one we call the main thread, and one is the garbage collector threads, the main thread end means the end of the program, the garbage collector thread is likely to be working.
2nd, wait () is similar to sleep (), where the thread is paused for a period of time, except that wait frees all locks held by the current thread, and sleep does not. We know that the only way to get a lock is to enter the synchronized Protection code snippet, so you'll find that wait is only available in the Synchronized method, and the direct write will give the warning that there is no lock for the current object. So notify with wait, notify will re-lock back to the blocked thread to continue execution, when there are multiple objects wait, notify not sure which one, must be locked only one, so the general use of Notifyall () To get them to compete for the only one lock on the priority level and so on, the competing thread executes, and the other threads just continue to wait.
In the past, Java allowed threads to be suspended outside a thread, that is, calling the Suspend method, which is extremely unsafe. According to object-oriented thinking, each object must be responsible for its own actions and encapsulate its own power. If any of the stepping objects can cause the thread to be blocked, the program tends to get messy and crashes, so the method is naturally shot down.
The last question is more interesting, the first answer is that the subclass rewrite F () method can be added synchronized also can not add, if added and also internally called SUPER.F (), the theory is that the same object should be added two locks, Because each call to the Synchronized method to add a, call the subclass of F first added a, into the method to call the parent class F also add a, plus two is not mutually exclusive? So the parent class F plus lock must always wait for an already added lock to release and cause a deadlock? In fact, this mechanism is called re-entry, when the parent class F method attempts to add a lock on this object, because the current thread has the lock of this object, it can also be understood as the key to open it, so the same thread on the same object has not been released before the second lock is not a problem, This lock actually does not add, it has the key, regardless of add a few or can enter the lock Protection Code section, unimpeded, so called re-entry, we can simply think that the second lock does not add.
In summary, the essence of synchronized is to keep other threads from adding a lock on the same object.
Java experience: Very inspiring (iv)