Sunday, September 20, 2015

Top of a page in Mac OSX

Shortcuts

Page Top (Home) - Command Up Arrow Key.

I had to google for far too long to discover the key above.

I've been going through a low intensity keyboard-shortcut-learning-spree as of late.  I've learned a number of new ones for windows, chrome, eclipse, and a couple for mac.  I find this to be highly effective during peer programming.

I'll compile a comprehensive list of the ones I know, sometime soon.

Saturday, June 13, 2015

Rant on the often condescending and patronizing culture on SE and SO

I often find myself reading articles on StackOverlow and StackExchange as part of my profession.  Often I find very useful posts that have been closed or flagged negatively in some way by one or many moderators, even though clearly the content is helpful to thousands, as evident in the up-votes, favourites, the number of answers, and constructive comments that are received on such posts.

There is a clear problem with this setup, as is evident in the tone of such flaggings.  Often there is a condescending, arrogant, and patronizing tone in such flaggings or some of the early comments by more experienced members.  This problem was recognized long ago in this post: Could we please be a bit nicer to new users? and the many comments and answers that follow below it, yet the problem still exists today - 6 years later.

I recently posted on the robotics stack exchange site, about an artificial intelligence topic that has been around for some time, though certainly not a mainstream topic.  Firstly, there is no AI SE site, and so I chose the robotics site.  Secondly, being my first post, I was excited and perhaps posted too many questions in that one post, as pointed out by the first comment, along with another correction in that comment:
"First, OP stands for "Original Poster" - the person that asked the question. This is you.  Second, questions that should be asked here are questions that are closed-ended, in that they should have 1 correct answer. The only question you have asked that meets this criteria is 1.3 ...  I would ask that you edit your question to only ask that one, and take all of the other questions to the Robotics chat room." 
The tone in the OP bit is obviously a bit blunt.  I assumed from other posts that OP may have meant Operator, analogous to Moderator (mod).  Well yeah, that would be me, thanks for pointing that out, twice.  I let go of that one quickly.

What actually irked me is this:
"Welcome to robotics ________, but I'm afraid that open ended questions like this really aren't a good fit for a stack exchange site. We prefer practical, answerable questions based on actual problems that you face. Take a look at How to Ask and tour for more information on how stack exchange works."

The second comment was posted after I had already changed the question I was asking to the one that qualified as not 'open-ended'.  With italics on top.  I've been on SO for over 3 years now, so I'm familiar with what constitutes a good question.  None of my questions have been negatively flagged on SO.  Though I haven't been a heavy user, I've been more of an 'asker' instead of an 'answerer' there, and so I know how to ask questions.  Was there really a need for a second redundant comment that is both trying to welcome me and moderate in the same sentence? Cookie-cutters aren't always necessary or appropriate.

Sometimes the arrogance is apparent in some of the mod's usernames, profiles, and obviously some of the comments they make.  It was more subtle, and perhaps more coordinated here.  The tone in these comments are not welcoming, rude, redundant, and certainly discouraging of a good discussion.  My question is certainly all if not most of these:
  • inspire answers that explain “why” and “how”
  • tend to have long, not short, answers 
  • have a constructive, fair, and impartial tone
  • invite sharing experiences over opinions insist that opinion be backed up with facts and references
  • are more than just mindless social fun

Wednesday, April 22, 2015

How to move a window back on screen in Windows

I run into this once in a while, and usually I've resolved it by right clicking on the relevant window's taskbar item, pressing ALT and then the down arrow key to get to the window menu where move is an option.

With windows 7 and 8, right clicking on the taskbar item no longer displays that menu, nor does the ALT + down always work.  So, here's what gets you to that menu for a given hidden taskbar item: ALT + SPACE.  Pressing M will select move.  Clicking the left or right arrow keys will move the window.

Friday, October 17, 2014

Switching between JDKs and Displaying Hidden Files on OSX 10.9.5

Switching between JDKs
Running Eclipse on OS X 10.9.5, one of the plugins I use warned me that it required Java 7 to run.  So I set out to install JDK 7.  My choices were to either replace JDK 6 with 7 or to install it alongside 6 and switch between the two if (when) required.  Both appeared straight forward choices, though I went with the latter so that I can just switch instead of re-installing when needed.

This required the setting of some environment variables, namely JAVA_HOME and the modification of PATH (which I'm used to doing quickly on Windows).  Not an expert OS X user, I thought of which 'top-most' config file to append these vars into so that all users (just cuz) and all launch methods would use them.  I remembered that .bashrc is part of a hierarchy that is used to construct the lookup path, and so I'd likely want to place it somewhere near root.  Since that file or no such related file exists there, I could have just modified the ones under my /Users/<user>/ dir.

Googling a bit further, I (re)learned of /etc/launchd.conf - config file for a launch daemon.  Then I stumbled upon this little handy tool Change Java version on Mac OS.  It didn't work at first.  Turns out that the /etc/launchd.conf file needs to be created if it doesn't exist; issued this to do that: sudo touch /etc/launchd.conf.  The tool worked after that.

Hidden Files

I also learned about a couple of ways to display hidden files in finder (didn't feel like cd'ing and using nano to check out launchd.conf, and just wanted to learn to do this anyway), though this didn't go as smoothly as expected.  At first I issued:
  • defaults write com.apple.Finder AppleShowAllFiles YES; killall Finder
Which didn't work, so I tried:
  • sudo chflags -R nohidden /*
Which also didn't work, so I found:
  • defaults write com.apple.Finder AppleShowAllFiles -bool YES; killall -HUP Finder
Which also didn't work at first, but strangely, re-issuing the first one (after some time) worked.  My guess is that finder didn't want to restart properly.  So, it is either the first or last one that worked.

Relevant links

Monday, January 6, 2014

Connecting to MSSQL Server from Java

I found this basic code snippet useful during the troubleshooting of a certain application-database connectivity issue.  It selects the date-time from the `master` DB, similar to Oracle's `dual` table used for testing purposes.  A DB user needs to exist, though you can probably use the default sysadmin `sa` user.  The project with this snippet needs to have the MSSQL JDBC driver (sqljdbc4.jar) on its project classpath.  As of now, version 4.0 of the driver can be run in JRE 7, but not JDK 7; it works fine in JDK 6.  Driver download link: Microsoft JDBC Driver 4.0 for SQL Server.

public class TestDBConnectivity { public static void main(String[] args) { String connectionUrl="jdbc:sqlserver://remoteServer:8081;DatabaseName=master;user=userName;Password=userPassword"; Connection con = null; Statement stmt = null; ResultSet rs = null; try { con = DriverManager.getConnection(connectionUrl); String SQL = "SELECT GETDATE() AS CurrentDateTime"; stmt = con.createStatement(); rs = stmt.executeQuery(SQL); while (rs.next()) { System.out.println("result: " + rs.getString("CurrentDateTime")); } } catch (Exception e) { e.printStackTrace(); } finally { if (rs != null) try { rs.close(); } catch(Exception e) {} if (stmt != null) { try { stmt.close(); } catch(Exception e) {} } if (con != null) { try { con.close(); } catch(Exception e) {} } } } }

Source: Connecting to SQL Server 2008 from Java

Monday, July 22, 2013

DB Isolation Levels, Locks, Dirty Reads, Non-Repeatable Reads, and Phantom Reads

A good wikipedia article on Isolation (of the I in ACID): https://en.wikipedia.org/wiki/Isolation_(database_systems).  Introduces well the concepts of the various levels of isolation, the required locking for each level, and the observed results per level.

Thursday, July 18, 2013

Maven built GWT Project in Eclipse Running on Standalone Tomcat 7


Vogella has an excellent tutorial on GWT in Eclipse here: GWT Tutorial.  Playing around with the 'userService' in Eclipse (just name changes of some resources), I decided to convert the GWT example to a maven gwt-archetype project.  


What's Needed


- Eclipse with m2e plugin and maven-gwt-plugin
- Tomcat 7 installation (OSX: download the tar and untar the dir wherever you want; I put it in /Applications/apache-tomcat-7.0.42)


Installing Plugins and Tomcat

Install the m2e plugin (through the 'Help->Install New Software...' link in Eclipse), as well as the maven-gwt-plugin (through modifying a dummy maven project's POM to include the plugin as a dependency).  I think this step is a bit awkward because you can't install the plugin through a site like you can the m2e plugin, but I am thankful to the developers who have created the plugin.  You can try to install it like how it's shown here, though I wasn't successful with this on two separate machines (gwt archetype wouldn't show in the filter list).  This didn't work either.

Install the Tomcat server by adding it in the Eclipse Preferences -> Server -> Runtime Environment -> Add.  Point it to your installation directory.  You should see it in Server view (Window -> Show View -> Other -> type: server).  Here's my setup: 
Right clicking the instance and going to properties shows the location.  Ensure it is not the workspace location.


Creating the Project


- Create a new 'Maven Project' in Eclipse (File->New->Other... type: 'maven')
- Uncheck 'Create simple project...' and click Next
- Type 'gwt' in the 'Filter' textbox and select 'gwt-maven-plugin'
- type your Group Id, Artifact Id, Package, and give the module the same name as that described in your *.gwt.xml file; ensure you are careful with all of these properties (uniform across other descriptors, property files, and code), and click Finish

Ensure your web.xml references your servlet name, servlet path, and the webapp (the HTML file in this tutorial) correctly!  The web.xml file will highlight a syntax error if the welcome-file-list is present before the servlet-mapping config.  Here is my web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
  
  <!-- Servlets -->
  <servlet>
    <servlet-name>userServlet</servlet-name>
    <servlet-class>test.server.MyUserServiceImpl</servlet-class>
  </servlet>
  
  <servlet-mapping>
    <servlet-name>userServlet</servlet-name>
    <url-pattern>/test/userService</url-pattern>
  </servlet-mapping>

  <!-- Default page to serve -->
  <welcome-file-list>
    <welcome-file>HelloUniverse.html</welcome-file>
  </welcome-file-list>


</web-app>

Ensure that your welcome HTML file correctly references the generated *.nocache.js file and other resources like CSS files:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <link type="text/css" rel="stylesheet" href="HelloUniverse.css">
    <title>Web Application Starter Project</title>
    
    <script type="text/javascript" language="javascript" src="hellouniverse/hellouniverse.nocache.js"></script>
  </head>

  <body>
</body>

</html> 

You also need to modify the project's Deployment Assembly property (right click the project -> Properties -> type: deployment, and it should pop up).  Add the /target/<project-name><version>-SNAPSHOT/<modulename> to be deployed on a directory <modulename> (hellounivere in my case):

Building and Running the Project

Now you can build the project by right clicking it-> Run As -> Maven Install.  Then add the project to the server by right clicking the server -> Add and Remove, then move to the right the project you want to deploy.

Go to your URL (localhost:8080/HelloUniverse) and the Click Me button should popup in a second.  If you don't, use the appropriate browser Developer Tools to debug.  A 404 on the *.nocache.js file is likely due to some issues in your web.xml or HTML file.  You should see this upon success:

Project Zip File

You can import my project and server setup from here.

Tuesday, March 19, 2013

A Note on String, StringBuffer, StringBuilder

When String (an immutable [not modifiable] type) construction or modification involving dynamic values (whose values are not known at compile time) is required by a single thread, the mutable StringBuilder will perform faster than StringBuffer.  The reason for the performance hit is likely that StringBuffer is thread-safe through synchronization.  StringBuilder is also mutable but not thread-safe, hence the faster predicted performance.

Saturday, March 9, 2013

My OS X Mountain Lion How-Tos, Shortcuts, & Notes

This collection of apps, how-tos, and notes is for my own record.  Hopefully someone will find them useful too.

Skipping .DS_store files while copying directories between two USB mounted volumes
rsync -rv --exclude=.DS_Store <source> <destination>
Source: Skipping .DS_Store files when copying between two external drives 

Showing and Hiding Hidden Files
defaults write com.apple.finder AppleShowAllFiles -boolean true
killall Finder

The reverse is
defaults delete com.apple.finder AppleShowAllFiles

killall Finder


Open Minimized Windows Using Command Tab
This is rather long.
1. Command + Tab to the window
2. unpress Tab
3. press and hold Option (alt)
4. unpress Command

For windows with multiple items open, play with the arrow keys

(Custom) Maximize Current Window (vertically)
Ctrl + m

Switching Between Multiple Safari Windows
Command + ~ (tilde)

Safari Tabs
Ctrl + Tab

Installing Tar Files (example)
   [frodo:~] testuser% tar xf fink-0.34.5.tar.gz
   [frodo:~] testuser% cd fink-0.34.5
   [frodo:~/fink-0.34.5] testuser% ./bootstrap

Building and Installing a C project?
./configure
make
sudo make install

or?

$ mkdir build
$ cd build
$ cmake ../
$ make
$ make install

Installing a Python project from tar

* Unpack: tar zxvf sslstrip-0.5.tar.gz
* Install twisted:  sudo apt-get install python-twisted-web
* (Optionally) run 'python setup.py install' as root to install,
 or you can just run it out of the directory.

IP Forwarding on OS X Lion+
It is a known fact that IP Forwarding (port forwarding) does not work on OS X Lion by default.
But there is a fix!
Modify your /Library/Preferences/SystemConfiguration/com.apple.Boot.plist file and a <string></string> tag set
with the following:
net.inet.ip.scopedroute=0

PATH in OS X Mountain Lion
/etc/paths
http://architectryan.com/2012/10/02/add-to-the-path-on-mac-os-x-mountain-lion
http://superuser.com/questions/28344/path-env-variable-on-mac-os-x-and-or-eclipse

Disable or modify mouse acceleration
SmoothMouse

Snap Windows to Corners
BetterTouchTool

Wednesday, February 27, 2013

Environment Variables in OSX 10.8.2

I'm still fairly new to OSX, and only recently started tinkering with env variables.  After some confusion on this SO thread, I found this pref pane to be very promising: EnvPane.

Thursday, February 21, 2013

Iterative Solution for Tower of Hanoi in Java

Going through some practice problems, and came across the Tower of Hanoi. The implementation of the iterative solution follows the following steps (borrowed from the wiki article):

"Simpler statement of iterative solution
Alternating between the smallest and the next-smallest disks, follow the steps for the appropriate case:
For an even number of disks:
-make the legal move between pegs A and B
-make the legal move between pegs A and C
-make the legal move between pegs B and C
-repeat until complete
For an odd number of disks:
-make the legal move between pegs A and C
-make the legal move between pegs A and B
-make the legal move between pegs C and B
-repeat until complete In each case, a total of 2ⁿ-1 moves are made."

Code: IterativeHanoi.java

Thursday, October 18, 2012

Classic Shell: great replacement for missing windows 8 start menu

http://classicshell.sourceforge.net/

Pokki constantly Page Faulting

I recently installed Windows 8 in Parallels. I was missing the old start menu, so I installed this app called Pokki. It's a replacement for the missing menu. I was checking out the new OS, going through the Task Manager, when I decided to add the Page Fault Delta and Threads columns under the Details tab, sorted by PF Delta, and noticed that there were two separate Pokki processes. The larger of the two with 29 threads was (is) constantly page faulting:

My mac is overheating, possibly in part due to this (and parallels itself), and I'm not running anything else intensive. I've contacted Pokki help/support, and I'll update with what they say. Edit: They replied saying that this behaviour is normal and should not be a cause for concern. Hm.

Tuesday, October 9, 2012

Demonstrating usage of a Binary Search Tree in Java

What is a Binary Search Tree?

Binary Search Tree (BST) is a tree in which each node has up to two child nodes (subtrees).  If pointers are used, then each node contains references to the left, right, and parent nodes.  Otherwise, like the implementation I found for Java, each node contains a left and right subtree in the form of a left and right node (each of which have their own two subtrees and so on...) along with the data associated with the node.

A BST is said to have a binary-search-tree property:

Let x be a node in a binary search tree. If y is a node in the left subtree of x, then key[y] <= key[x]. If y is a node in the right subtree of x, then key[x] <= key[y].1

Since Java doesn't have pointers that we can use, we won't keep track of keys. We'll work directly with node data.

Cormen et-all mention that BSTs support the following operations:

Search trees are data structures that support many dynamic-set operations, including
SEARCH, MINIMUM, MAXIMUM, PREDECESSOR, SUCCESSOR, INSERT, and
DELETE. Thus, a search tree can be used both as a dictionary and as a priority
queue.


What are some applications of BST?

This StackOverflow question answers this well:
What are the applications of binary trees?

Apparently, it is also used in the solution to the Traveling Salesman Problem and the related Shortest Path Problem. I'll be checking these out soon.


How do I use a BST in Java?

I found a good Java BST impl here:
BST.java
BSTNode.java

Class BST contains a root BSTNode node and provides most BST operations (as identified by Cormen et-all). The PREDECESSOR and SUCCESSOR operations are not implemented. Search is implemented, though not exposed directly (it's exposed as isInTree(T el)).

I've slapped together an Eclipse project that demonstrates the usage of this BST implementation. I added some code to BST.java (the one in the Eclipse project) borrowed from this Stanford CS Library page on BSTs. I also borrowed some inspiration from this SO page: How to print binary tree diagram. The class BTreePrinter in the project is pretty much directly from this SO page.

It would be worthwhile to study at least the BST.java and BSTNode.java.

>Download BST_Demo (Eclipse Project)

Here is the output:


>String arrays:
ACEG:  [Aliyah, Chris, Elijah, Gamal]
BDFH:  [Brian, Doug, Farah, Hasan]

>Insert ACEG:
Aliyah Chris Elijah Gamal 

>Insert BDFH:
Aliyah Brian Chris Doug Elijah Farah Gamal Hasan 

>Removing 'Aliyah':
Brian Chris Doug Elijah Farah Gamal Hasan Aliyah Brian Chris Chris Doug Elijah Elijah Farah Gamal Gamal Hasan 

>Clearing bst.

>Reinserting both arrays:
Aliyah Brian Chris Doug Elijah Farah Gamal Hasan 

>Search for 'Irene':
false

>Search for 'Aliyah':
true

>Postorder: 
Brian Doug Farah Hasan Gamal Elijah Chris Aliyah 
>Postorder (iterative): 
Brian Doug Farah Hasan Gamal Elijah Chris Aliyah 
>Postorder (Morris): 
Brian Doug Farah Hasan Gamal Elijah Chris Aliyah 

>Preorder: 
Aliyah Chris Brian Elijah Doug Gamal Farah Hasan 
>Preorder (iterative): 
Aliyah Chris Brian Elijah Doug Gamal Farah Hasan 
>Preorder (Morris): 
Aliyah Chris Brian Elijah Doug Gamal Farah Hasan 

>Size:
8

>Max depth:
5

>Min val:
Aliyah

>Max val:
Hasan

Aliyah Brian Chris Doug Elijah ElijahGamal Farah Gamal Hasan 

>Print all root-leaf paths:
Aliyah Chris Brian 
Aliyah Chris Elijah Doug 
Aliyah Chris Elijah Gamal Farah ElijahGamal 
Aliyah Chris Elijah Gamal Hasan 


>Mirroring bst:
Aliyah Brian Chris Doug Elijah ElijahGamal Farah Gamal Hasan 
Hasan Gamal Farah ElijahGamal Elijah Doug Chris Brian Aliyah 

>Doubling bst:
Hasan Hasan Gamal Gamal Farah Farah ElijahGamal ElijahGamal Elijah Elijah Doug Doug Chris Chris Brian Brian Aliyah Aliyah 

>bst:
Aliyah Brian Chris Doug Elijah Farah Gamal Hasan 
>bst2:
Aliyah Brian Chris Doug Elijah Farah Gamal Hasan 
>bst identical to bst2?:
true

>Possible unique trees given this bst's size: (8)
1430

>Check bst:
true

>Printing bst (bad spacing):
               Aliyah                               
                      \               
                       \              
                        \             
                         \            
                          \           
                           \          
                            \         
                             \        
                       Chris               
                      /      \       
                     /        \      
                    /          \     
                   /            \    
                   Brian       Elijah       
                          /       \   
                         /         \  
                         Doug   Gamal   
                            /      \ 
                            Farah Hasan 
                                                                

>Another bst print:
'- Aliyah
    '- Chris
        '- Brian
        '- Elijah
            '- Doug
            '- Gamal
                '- Farah
                '- Hasan

>Inst and init int bst (unbalanced because of ordered insert):
'- 1
    '- 2
        '- 3
            '- 4

Unbalanced integer tree:
       1               
        \       
         \      
          \     
           \    
           2       
            \   
             \  
             3   
              \ 
              4 
                                

Cleared and intBst.balance(intArr):
'- 2
    '- 1
    '- 3
        '- 4

>Balanced integer tree:
   2       
  / \   
 /   \  
 1   3   
      \ 
      4 
                


1 Introduction to Algorithms Second Edition (Cormen, Leiserson, Rivest, Stein), page 254

Thursday, October 4, 2012

Synchronization and Thread Safety in Hashtable, Hashmap, ConcurerntHashMap

Coming across blog entry "Who said Java Hashtable is thread safe?", I decided to run the code.  He's right in saying that Hashtable isn't thread safe, though, I don't think such a claim was ever officially made.  Maybe if there is allusion among some that it is, then I suppose it needs dispelling.  Thread safety is a design challenge.  Fully synchronized classes, and even completely thread-safe classes can be used inefficiently, or worse, incorrectly, in a concurrent system.

Here are three examples of thread unsafe usage, followed by three examples of safe usage:

1. Unsafe

package unsafe.demo;

import java.util.HashMap;
import java.util.Map;

import unsafe.threads.Unsafe_Hashmap_NoSynchronized_NotUsingContainsKey;

public class DemoThreadUnsafe {
  private Map<Integer, String> map = new HashMap<Integer, String>();

  public static void main(String[] args) throws InterruptedException {
    for (int j = 1; j < 200; j++) {
      DemoThreadUnsafe demoClass = new DemoThreadUnsafe();
      for (int i = 0; i < 5; i++) {
        new Thread(new Unsafe_Hashmap_NoSynchronized_NotUsingContainsKey(demoClass.map)).start();
      }
      Thread.currentThread().sleep(10);
      System.out.println(demoClass.map.keySet());
      demoClass.map.clear();
    }
  }
}

1. Unsafe cont.

package unsafe.threads;

import java.util.Map;

/**
 * put operation is not safe on the map because its impl in 
 * hashmap (used by calling thread) is not synchronized
 * based on: http://lovehasija.com/2012/08/16/who-said-java-hashtable-is-thread-safe/
 * 
 * @author sshakil
 *
 */
public class Unsafe_Hashmap_NoSynchronized_NotUsingContainsKey implements Runnable {
  private Map<Integer, String> map = null;

  public Unsafe_Hashmap_NoSynchronized_NotUsingContainsKey(Map<Integer, String> map) {
    this.map = map;
  }

  @Override
  public void run() {
    for (int i = 1; i <= 30; i++) {
      try {
        map.put(i, Thread.currentThread().getName());
      } catch (Exception e) {
        System.out.println(e);
      }

    }
  }
}



2. Unsafe
package unsafe.demo;

import java.util.Hashtable;
import java.util.Map;

import unsafe.threads.Unsafe_Hashtable_NoSynchronized_UsingContainsKey;

public class DemoThreadUnsafe2 {
  private static volatile Map<Integer, String> map = new Hashtable<Integer, String>();

  public static void main(String[] args) throws InterruptedException {
    for (int j = 1; j < 200; j++) {
      DemoThreadUnsafe2 demoClass = new DemoThreadUnsafe2();
      for (int i = 0; i < 10; i++) {
        new Thread(new Unsafe_Hashtable_NoSynchronized_UsingContainsKey(demoClass.map)).start();
      }
      Thread.currentThread().sleep(100);
      demoClass.map.clear();
    }
  }
}


2. Unsafe cont.

package unsafe.threads;

import java.util.Map;

/**
 * the sequence of map.containsKey(i) followed by the map.put sequence is not
 * safe because map's impl in hashmap (used by calling thread) is not
 * synchronized based on:
 * http://lovehasija.com/2012/08/16/who-said-java-hashtable-is-thread-safe/
 * 
 * @author sshakil
 * 
 */
public class Unsafe_Hashtable_NoSynchronized_UsingContainsKey implements Runnable {

  private static volatile Map<Integer, String> map = null;

  public Unsafe_Hashtable_NoSynchronized_UsingContainsKey(Map<Integer, String> map) {
    this.map = map;
  }

  @Override
    public void run() {

         for (int i = 1; i <= 30; i++) {
          synchronized(map) {
             if(!map.containsKey(i)) {
                 //some other thread can modify data between the execution of 
                 //above and below lines
                 //try to catch it:
                 if(map.containsKey(i)) {
                   try {
              throw new Exception ("Detected mofification by another thread.");
            } catch (Exception e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
            }
                 }
                 //more modifications can occur any time in above block
                System.out.println( Thread.currentThread().getName() 
                    + "\tInserting new, Key exists: " + map.containsKey(i));
                map.put(i, Thread.currentThread().getName());
             }
             }
        }
    }
}


3. Unsafe

package unsafe.demo;

import java.util.concurrent.ConcurrentHashMap;

import safe.threads.Safe_Hashtable_Synchronized_UsingContainsKey;
import unsafe.threads.Unsafe_ConcurrentHashMap_NoSynchronized_UsingContainsKey;


public class DemoThreadUnsafe3 {

  // private Map<Integer, String> map = new Hashtable<Integer, String>();
  private ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<Integer, String>();

  public static void main(String[] args) throws InterruptedException {

    for (int j = 1; j < 2000; j++) {
      DemoThreadUnsafe3 demoClass = new DemoThreadUnsafe3();

      for (int i = 0; i < 15; i++) {
        new Thread(
            new Unsafe_ConcurrentHashMap_NoSynchronized_UsingContainsKey(demoClass.map))
              .start();
      }

      Thread.currentThread().sleep(1);
      demoClass.map.clear();
    }
  }

}

3. Unsafe cont.

package unsafe.threads;
import java.util.Map;


public class Unsafe_ConcurrentHashMap_NoSynchronized_UsingContainsKey implements Runnable {
 
    private Map<Integer, String> map = null;
 
    public Unsafe_ConcurrentHashMap_NoSynchronized_UsingContainsKey(Map<Integer, String> map) {
         this.map = map;
    }
 
    @Override
    public void run() {

         for (int i = 1; i <= 30; i++) {
           //synchronized(map) {
               if(!map.containsKey(i)) {
                   if(map.containsKey(i)){
                     System.out.println("TRUE?");
                     try {
                throw new Exception("this can't be!");
              } catch (Exception e) {
                e.printStackTrace();
              }
                   }
                  System.out.println( Thread.currentThread().getName() 
                      + "\tInserting new, Key exists: " + map.containsKey(i));
                  map.put(i, Thread.currentThread().getName());
              }
           //}
        }
    }
}


Examples of safe usage:

1. Safe

package safe.demo;

import java.util.Hashtable;

import safe.threads.Safe_Hashtable_NoSynchronize_UsingPut;

/**
 * Thread safe hashmap usage through the use of 'synchronized' keyword. Based
 * on: http://lovehasija.com/2012/08/16/who-said-java-hashtable-is-thread-safe/
 * 
 * @author sshakil
 * 
 */
public class PartiallySafe_BecauseOfHashtable {

  // private Map<Integer, String> map = new Hashtable<Integer, String>();
  private Hashtable<Integer, String> map = new Hashtable<Integer, String>();

  public static void main(String[] args) throws InterruptedException {

    for (int j = 1; j < 100; j++) {
      PartiallySafe_BecauseOfHashtable demoClass = new PartiallySafe_BecauseOfHashtable();

      for (int i = 0; i < 5; i++) {
        new Thread(new Safe_Hashtable_NoSynchronize_UsingPut(demoClass.map)).start();
      }

      Thread.currentThread().sleep(10);
      System.out.println(demoClass.map.keySet());
      demoClass.map.clear();
    }
  }
}


1. Safe cont.

package safe.threads;

import java.util.Map;

/**
 * put operation is not safe on the map because its impl in 
 * hashmap (used by calling thread) is not synchronized
 * based on: http://lovehasija.com/2012/08/16/who-said-java-hashtable-is-thread-safe/
 * 
 * @author sshakil
 *
 */
public class Safe_Hashtable_NoSynchronize_UsingPut implements Runnable {
  private Map<Integer, String> map = null;

  public Safe_Hashtable_NoSynchronize_UsingPut(Map<Integer, String> map) {
    this.map = map;
  }

  @Override
  public void run() {
    for (int i = 1; i <= 30; i++) {
      try {
        map.put(i, Thread.currentThread().getName());
      } catch (Exception e) {
        System.out.println(e);
      }

    }
  }
}

2. Safe


package safe.demo;

import java.util.concurrent.ConcurrentHashMap;

import safe.threads.Safe_ConcurrentHashMap_NoSynchronize_UsingPutIfAbsent;

public class Safe_ConcurrentHashMap {

  private ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<Integer, String>(
      80, 0.5f, 200);

  // private Map<Integer, String> map = new HashMap<Integer, String>();

  public static void main(String[] args) throws InterruptedException {

    for (int j = 1; j < 100; j++) {
      Safe_ConcurrentHashMap demoClass = new Safe_ConcurrentHashMap();
      for (int i = 0; i < 5; i++) {
        new Thread(
              new Safe_ConcurrentHashMap_NoSynchronize_UsingPutIfAbsent(demoClass.map))
                .start();
      }

      Thread.currentThread().sleep(10);
      System.out.println(demoClass.map.keySet());
      demoClass.map.clear();
    }
  }
}


2. Safe cont.


package safe.threads;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Thread safe hashmap usage through the use of 'synchronized' keyword based on:
 * http://lovehasija.com/2012/08/16/who-said-java-hashtable-is-thread-safe/
 * 
 * @author sshakil
 */
public class Safe_ConcurrentHashMap_NoSynchronize_UsingPutIfAbsent implements Runnable {

  //private Map<Integer, String> map = null;
  private ConcurrentHashMap<Integer, String> map = null;

  public Safe_ConcurrentHashMap_NoSynchronize_UsingPutIfAbsent(
      ConcurrentHashMap<Integer, String> map) {
  //public ThreadSafeMapUsage3(Map<Integer, String> map) {
    this.map = map;
  }

  @Override
  public void run() {
    for (int i = 1; i <= 30; i++) {
      //String result = map.put(i, Thread.currentThread().getName());
      String result = map.putIfAbsent(i, Thread.currentThread().getName());    
    }
  }
}


3. Safe

package safe.demo;

import java.util.concurrent.ConcurrentHashMap;

import safe.threads.Safe_ConcurrentHashMap_NoSynchronize_UsingPutIfAbsent;

public class Safe_ConcurrentHashMap {

  private ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<Integer, String>(
      80, 0.5f, 200);

  // private Map<Integer, String> map = new HashMap<Integer, String>();

  public static void main(String[] args) throws InterruptedException {

    for (int j = 1; j < 100; j++) {
      Safe_ConcurrentHashMap demoClass = new Safe_ConcurrentHashMap();
      for (int i = 0; i < 5; i++) {
        new Thread(
              new Safe_ConcurrentHashMap_NoSynchronize_UsingPutIfAbsent(demoClass.map))
                .start();
      }

      Thread.currentThread().sleep(10);
      System.out.println(demoClass.map.keySet());
      demoClass.map.clear();
    }
  }

}


3. Safe cont.

package safe.threads;

import java.util.Map;

/**
 * Thread safe hashmap usage through the use of 'synchronized' keyword based on:
 * http://lovehasija.com/2012/08/16/who-said-java-hashtable-is-thread-safe/
 * 
 * @author sshakil
 */
public class Safe_Hashtable_Synchronized_UsingContainsKey implements Runnable {

  private Map<Integer, String> map = null;

  public Safe_Hashtable_Synchronized_UsingContainsKey(Map<Integer, String> map) {
    this.map = map;
  }

  @Override
  public void run() {

    for (int i = 1; i <= 30; i++) {
      synchronized (map) {
        if (!map.containsKey(i)) {
          if (map.containsKey(i)) {
            System.out.println("TRUE?");
            try {
              throw new Exception("this can't be!");
            } catch (Exception e) {
              e.printStackTrace();
            }
          }
          System.out.println(Thread.currentThread().getName()
              + "\tInserting new, Key exists: "
              + map.containsKey(i));
          map.put(i, Thread.currentThread().getName());
        }
      }
    }
  }
}