Suggestions on solving Java programming language thread problems (4)

Source: Internet
Author: User
Suggestions for solving Java programming language thread problems (4) -- Linux general technology-Linux programming and kernel information, the following is a detailed description. Access problems

The lack of good access control will make thread programming very difficult. In most cases, if the thread can be called only from the synchronization subsystem, the thread safety issue does not need to be considered. I suggest
The access permission concept of Java programming language is subject to the following restrictions;

Precise use of package
Keyword to restrict package access. I think that the existence of the default behavior is a flaw in any computer language, and I am confused about the existence of this default permission (and this default is "package) "level rather than" private )").
In other aspects, the Java programming language does not provide equivalent default keywords. Although an explicit package is used
But it makes the code more readable and can eliminate potential errors of the entire class.
(For example, if the access permission is ignored due to an error, rather than being ignored intentionally ).


Introduce private protected again. Its function should be consistent with the current protected
The same, but the package-level access should not be allowed.


Allow the private syntax to specify "implemented access". It is private to all external objects, and even the current object is of the same class. The only reference (implicit or explicit) on the left of "." should be
This.


Extends the public syntax to authorize it to create access to specific classes. For example, the following code should allow
The object of the Fred class can be called with some_method (), but this method should be private for objects of other classes.


Public (Fred) void some_method ()
{
}




This suggestion is different from the "friend" mechanism of C ++. In the "friend" mechanism, it authorizes one class to access all the private parts of the other class. Here, I suggest strictly controlling access to a limited set of methods. In this way, a class can define an interface for another class, which is invisible to other classes of the system. An obvious change is:


Public (Fred, Wilma) void some_method ()
{
}





Unless the domain references an object that is immutable or basic type of static final, the definition of all domains should be
Private. Direct access to a domain in a class violates two basic rules designed by OO: Abstraction and encapsulation. From the thread's point of view, allowing direct access to the domain only makes it easier to perform non-synchronous access to it.



Add the $ property keyword. An object with this keyword can be
Box "application access, which uses the introspection API defined in the Class, otherwise it will be the same as private. $ Property
Attributes can be used in fields and methods, so that the existing JavaBean getter/setter method can be easily defined as attributes.


Immutability)

Because the access to unchanged objects does not need to be synchronized, the immutable concept (the value of an object cannot be changed after it is created) in the multi-threaded environment is priceless. Java
In programming languages, there are two reasons for the implementation of immutability:


You can access a constant object before it is completely created. Such access may produce incorrect values for some domains.


The definition of a constant (all fields of the class are final) is too loose. For
Final references the specified object. Although the reference itself cannot be changed, the object itself can be changed.

The first problem can be solved. The thread cannot be executed in the constructor.
(Or the start request cannot be executed before the constructor returns ).


The second problem can be solved by specifying the final modifier to point to a constant object. This means that for an object, only all the fields are
Final, and all referenced object fields are also final. This object is really constant. In order not to break the existing code, this definition can be enhanced using the compiler, that is, this class is the same class only when a class is explicitly labeled unchanged. The method is as follows:




$ Immutable public class Fred
{
// All fields in this class must be final, and if
// Field is a reference, all fields in the referenced
// Class must be final as well (recursively ).

Static int x constant = 0; // use of 'final' is optional when $ immutable
// Is present.
}





With the $ immutable modifier, the final modifier in the domain definition is optional.


Finally, when an inner class is used, an error in the Java compiler makes it unable to reliably create unchanged objects. When a class has an important internal class (which is common in my code), the compiler often incorrectly displays the following error message:

"Blank final variable 'name' may not have been initialized.
It must be assigned a value in an initializer, or in every constructor ."



This error message is returned even if the empty final is initialized in each constructor. Since
This error persists in the compiler after internal classes are introduced in version 1.1. In this version (three years later), this error still exists. Now it is time to correct this error.



Instance-level access to a class-level domain

In addition to access permissions, there is also a problem: both the class-level (static) method and the instance (non-static) method can directly access the class-level (static) domain. This access is very dangerous, because the synchronization of instance methods does not obtain the class-Level Lock, so
Synchronized static method and a synchronized
The method can still be used by the callback class at the same time. An obvious way to correct this problem is to use only the instance method
The static access method can only access the static
Domain. Of course, this requirement requires the compiler and runtime check. In this case, the following code is invalid:

Class Broken
{
Static long x;

Synchronized static void f ()
{X = 0;
}

Synchronized void g ()
{X =-1;
}
};




Because f () and g ()
Can run in parallel, so they can change x at the same time
). Remember, there are two locks: static
The method must be a lock of the Class Object, rather than a static method. When you access a non-unchanged static domain from an instance method, the compiler must satisfy any of the following two structures:




Class Broken
{
Static long x;

Synchronized private static accessor (long value)
{X = value;
}

Synchronized static void f ()
{X = 0;
}

Synchronized void g ()
{Accessor (-1 );
}
}





Or, the compiler should obtain the use of the read/write lock:



Class Broken
{
Static long x;

Synchronized static void f ()
{$ Writing (x) {x = 0 };
}

Synchronized void g ()
{$ Writing (x) {x =-1 };
}
}





Another method is (this is also an ideal method)-the compiler should automatically use a read/write lock to synchronously access non-unchanged static domains, so that programmers do not have to worry about this problem.

End of background thread

When all non-Background threads are terminated, the background threads are suddenly terminated. When the background thread creates some global resources (such as a database connection or a temporary file) and the background thread ends, these resources are not closed or deleted, which may cause problems.


For this problem, we recommend that you set rules so that the Java Virtual Machine does not close the application in the following cases:


Any non-Background thread is running, or:

Any background thread is executing a synchronized method or a synchronized code block.


The background thread can be immediately shut down after it executes the synchronized block or the synchronized method.


Re-introduce stop (),
Suspend () and resume ()
Keywords

This may not work for practical reasons, but I want not to abolish stop () (in Thread and ThreadGroup ). However, I will change stop ()
So that existing code is not destroyed when calling it. However, for the stop () issue, remember that when the thread ends, stop ()
All locks will be released, which may potentially bring the thread working on this object into an unstable (locally modified) state. Since the stopped thread has released all the locks on this object, these objects cannot be accessed again.


To solve this problem, you can redefine the stop () action so that the thread can be terminated immediately only when no lock is occupied. If it occupies the lock, I suggest terminating it only after this thread releases the last lock.
You can use a mechanism similar to throwing an exception to implement this behavior. The stopped thread should set a flag and immediately test it when exiting all synchronization blocks. If this flag is set, an implicit exception is thrown,
However, this exception should no longer be captured and no output will be generated when the thread ends. Note that Microsoft's NT operating system cannot handle a sudden stop (abrupt) of an external indication ). (It does not
The stop message notifies the dynamic Connection Library, which may cause system-level resource vulnerabilities .) This is why I recommend that you use a method similar to an exception to simply result in the return of run.


The actual problem with handling methods similar to this exception is that you must
Insert code after the block to test the "stopped" flag. In addition, this additional code will reduce system performance and increase the code length. Another method I think of is to make stop ()
Implement a "lazy" Stop. In this case ()
Or yield. I also want
Add an isStopped () and stopped () method
(At this time, Thread will be like isInterrupted () and interrupted ()
It works the same way, but it detects the "stop-requested" status ). This method is not as common as the first one, but is feasible and does not produce overload.


The suspend () and resume () methods should be put back to Java
They are useful in programming languages and I don't want to be considered kindergarten children. It is unreasonable to remove them because they may cause potential risks (when suspended, a thread can occupy a lock. Please let me decide whether to use them.
If the received threads are occupying the lock, Sun should treat them as a run-time exception (run-time exception) that calls suspend (); or a better way is, delay the actual suspension process until the thread releases all locks.


The blocked I/O should work properly

It should be able to interrupt any blocked operations, instead of simply making them wait ()
And sleep (). I have discussed this issue in the socket section in chapter 2 of "Taming Java Threads. But now, for a blocked socket
The only way to interrupt an I/O operation is to close the socket, but there is no way to interrupt a blocked file I/O operation. For example, once a Read Request starts and enters the blocking status, unless it actually reads something,
Otherwise, the thread is always blocked. The read operation cannot be interrupted even if the file handle is disabled.


In addition, the program should support I/O operation timeout. All objects that may block operations (such as InputStream objects) should also support this method:

InputStream s = ...;
S. set_timeout (1000 );





This is the same as setSoTimeout (time) of the Socket class)
The method is equivalent. Similarly, timeout must be passed as a parameter to a blocked call.


ThreadGroup class

ThreadGroup should implement all the methods in Thread that can change the Thread state. I especially want it to implement the join () method, so that I can wait for the termination of all threads in the group.


Summary

The above is my suggestion. As I said in the title, if I am a king... (AH ). I hope these changes (or other equivalent methods) will eventually be introduced.
Java language. I do think that Java is a great programming language, but I also think that the Java thread model is not well designed. This is a pity. However, Java
Programming languages are evolving, so there are still prospects for improvement.

References

This article is an excerpt from the update of Taming Java Threads. This book
The traps and problems of multi-thread programming in Java are discussed, and a thread-related Java package is provided to solve these problems.


The University of Maryland's Bill put in the process of modifying JLS to improve its thread model. Bill's proposal is not as broad as this article suggests. He is mainly committed to making the existing thread model run in a more rational way. For more information, see www.cs.umd.edu /~ You can obtain the data by using the API, java, and memoryModel.


All Java language specifications can be found on Sun's website.


To examine the thread from a purely technical perspective, see Concurrent Programming in Java: Design Principles and Patterns second edition compiled by Doug Lea. This is a great book, but its style is academic and not necessarily suitable for all readers. It is a good supplement to "Taming Java Threads.


Java Threads compiled by Scott Oaks and Henry Wong are lighter than Taming Java Threads, but it is more suitable if you have never written a thread program. Oaks and Wong also implement the help classes provided by Holub, and it is always helpful to look at different solutions to the same problem.


Threads Primer: A Guide to Multithreaded Programming compiled by Bill Lewis and Daniel J. Berg is A good introduction to Threads (not limited to Java.

Some technical information about Java threads can be found on the Sun website.

In "Multiprocessor Safety and Java", Paul Jakubik discusses the SMP problem of multithreading systems.


Author Profile

Allen Holub has been devoted to the computer industry since 1979. He is in various magazines
(Dr. Dobb's Journal, Programmers Journal, Byte, MSJ, and other magazines) published a large number of articles. He is an online magazine
Java World
Toolbox column, also for IBM
Write the "OO-design process" section in the developerWorks component technology area. He also leads
ITWorld programming theory and practice discussion group.


Allen has written eight books, and a new book recently discussed the Java thread traps and defects "Taming Java Threads". He has been engaged in designing and compiling object-oriented software for a long time. Engaged in
After eight years of C ++ programming, Allen switched from C ++ to Java in 1996. He now regards C ++ as a nightmare, and his terrible experiences are gradually being forgotten. Since 1982, he has taught himself computer programming for the University of California at Berkeley (first
C, then C ++ and MFC. Now it is object-oriented design and Java ). Allen also provides public and in-house courses in Java and object-oriented design. He also provides Object-Oriented Design Consulting and contracts Java programming projects. Please contact Allen through this Web site and get information: www.holub.com.
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.