Observations on the assured evolution of concurrent Java programs

Aaron Greenhouse, T.J. Halloran, William L. Scherlis
2005 Science of Computer Programming  
Evolving and refactoring concurrent Java software can be error-prone, resulting in race conditions and other concurrency difficulties. We suggest that there are two principal causes: concurrency design intent is often not explicit in code and, additionally, consistency of intent and code cannot easily be established through either testing or inspection. We explore several aspects of this issue in this paper. First, we describe a tool-assisted approach to modeling and assurance for concurrent
more » ... grams. Second, we give an account of recent case study experience on larger-scale production Java systems. Third, we suggest an approach to scalable co-evolution of code and models that is designed to support working programmers without special training or incentives. Fourth, we propose some concurrency-related refactorings that, with suitable analysis and tool support, can potentially offer assurances of soundness. Adoptability and scalability. Addressing these two questions, particularly in the case of fast-paced iterative development environments, can be highly problematic. While programmers may communicate design intent informally among themselves, there has been relatively little success in capturing intent in sufficiently precise representations that tools can be used to assist in assuring consistency. The high "expression cost" often creates an effective adoption barrier, and the well-known difficulties in general-purpose assurance for larger systems create an effective scaling barrier. Generally, the only exceptions are small components of highly critical systems. As a consequence, there is a perception that both the expression of model information and the assurance of its consistency with the code present an overwhelming barrier to providing deep analytic assurance for routine Java programming efforts. The experience of many projects suggests that the barrier involves both usability and scalability. Usability barriers include ease of expression of design intent, ease of use of analysis tools, value of information provided, etc. Scalability barriers include extent of design intent information to be expressed and difficulty of the analysis task as a function of the scale and complexity of the code. One of the challenges in modeling and reasoning about concurrency is that most interesting concurrency-related properties defy both traditional testing and inspection techniques. There is no single place in the code to look to find either expression of model information or evidence of compliance. In particular, the reasoning process to ensure consistency of code and model is almost always non-local in the structure of the code. This raises a challenge for programmers attempting to accomplish informal reverse engineering-often of their own code-and also for tool developers seeking to assist in evolving and assuring concurrent Java programs. We present here an approach to concurrency-related assurance and evolution designed to address these challenges of practicability and scale. Our approach is to identify small compromises of inferential and expressive power that yield big improvements in adoptability for working programmers as well as in scalability to components and systems of realistic size. In the sections below, we present our approach to modeling and reasoning about Java concurrency. As noted, there are specific limits we accept on expressiveness and power to achieve this. In particular, rather than requiring a programmer to express and verify full representation invariants for data structures, we instead substitute a model of "guilt-by-association", in which those constituents of shared state that participate in some notional representation invariant are associated with each other into "regions" [18, 16] . Race conditions, by definition, occur when a representation invariant is expected to hold at a place where in fact it does not, due to the interleaved execution of a separate thread. In our approach, we focus on identifying the constituents of state that might be related by a putative invariant, but we avoid elucidating their precise relationship. The hypothesis underlying this approach is that modeling at this more abstract level can provide concrete value in establishing safe concurrency. This has been reinforced through extensive case study experience. Approach and prior work. Our approach has four elements: (1) The incremental expression of "mechanical" design intent (what some call "nonfunctional" requirements) for Java concurrency.
doi:10.1016/j.scico.2005.03.002 fatcat:dtnbnbspsvhlxe3kndt7whi2qa