KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > puppycrawl > tools > checkstyle > checks > coding > DoubleCheckedLockingCheck


1 ////////////////////////////////////////////////////////////////////////////////
2
// checkstyle: Checks Java source code for adherence to a set of rules.
3
// Copyright (C) 2001-2005 Oliver Burn
4
//
5
// This library is free software; you can redistribute it and/or
6
// modify it under the terms of the GNU Lesser General Public
7
// License as published by the Free Software Foundation; either
8
// version 2.1 of the License, or (at your option) any later version.
9
//
10
// This library is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
// Lesser General Public License for more details.
14
//
15
// You should have received a copy of the GNU Lesser General Public
16
// License along with this library; if not, write to the Free Software
17
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
////////////////////////////////////////////////////////////////////////////////
19
package com.puppycrawl.tools.checkstyle.checks.coding;
20
21 import antlr.collections.AST;
22 import com.puppycrawl.tools.checkstyle.api.Check;
23 import com.puppycrawl.tools.checkstyle.api.DetailAST;
24 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
25
26 /**
27  * Detect the double-checked locking idiom, a technique that tries to avoid
28  * synchronization overhead but is incorrect because of subtle artifacts of
29  * the java memory model.
30  *
31  * See <a HREF=
32  * "http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html"
33  * >The &quot;Double-Checked Locking is Broken&quot; Declaration</a> for a
34  * more in depth explanation.
35  *
36  * @author Lars K&uuml;hne
37  */

38 public class DoubleCheckedLockingCheck extends Check
39 {
40     /** {@inheritDoc} */
41     public int[] getDefaultTokens()
42     {
43         return new int[]{TokenTypes.LITERAL_IF};
44     }
45
46     /** {@inheritDoc} */
47     public void visitToken(DetailAST aAST)
48     {
49         final DetailAST synchronizedAST =
50             getLowestParent(aAST, TokenTypes.LITERAL_SYNCHRONIZED);
51         if (synchronizedAST == null) {
52             return;
53         }
54
55         final DetailAST ifAST =
56             getLowestParent(synchronizedAST, TokenTypes.LITERAL_IF);
57         if (ifAST == null) {
58             return;
59         }
60
61         if (getIfCondition(aAST).equalsTree(getIfCondition(ifAST))) {
62             log(aAST.getLineNo(), aAST.getColumnNo(),
63                 "doublechecked.locking.avoid");
64         }
65     }
66
67     /**
68      * returns the condition of an if statement.
69      * @param aIfAST the LITERAL_IF AST
70      * @return the AST that represents the condition of the if statement
71      */

72     private AST getIfCondition(DetailAST aIfAST)
73     {
74         return aIfAST.getFirstChild().getNextSibling();
75     }
76
77     /**
78      * searches towards the root of the AST for a specific AST type.
79      * @param aAST the starting node for searching (inclusive)
80      * @param aTokenType the token type to search for
81      * @return the first token of type aTokenTye or null if no such token exists
82      */

83     private DetailAST getLowestParent(DetailAST aAST, int aTokenType)
84     {
85         DetailAST synchronizedParent = aAST;
86         while ((synchronizedParent != null)
87                && (synchronizedParent.getType() != aTokenType))
88         {
89             synchronizedParent = synchronizedParent.getParent();
90         }
91         return synchronizedParent;
92     }
93 }
94
Popular Tags