expvar: sort maps, fix race

It's pretty distracting to use expvar with the output of both
the top-level map and map values jumping around randomly.

Also fixes a potential race where multiple clients trying to
increment a map int or float key at the same time could lose
updates.

R=golang-codereviews, couchmoney
CC=golang-codereviews
https://golang.org/cl/54320043
diff --git a/src/pkg/expvar/expvar_test.go b/src/pkg/expvar/expvar_test.go
index 572c62b..d2ea484 100644
--- a/src/pkg/expvar/expvar_test.go
+++ b/src/pkg/expvar/expvar_test.go
@@ -5,7 +5,10 @@
 package expvar
 
 import (
+	"bytes"
 	"encoding/json"
+	"net/http/httptest"
+	"strconv"
 	"testing"
 )
 
@@ -15,6 +18,7 @@
 	mutex.Lock()
 	defer mutex.Unlock()
 	vars = make(map[string]Var)
+	varKeys = nil
 }
 
 func TestInt(t *testing.T) {
@@ -139,3 +143,25 @@
 		t.Errorf(`f.String() = %q, want %q`, s, exp)
 	}
 }
+
+func TestHandler(t *testing.T) {
+	RemoveAll()
+	m := NewMap("map1")
+	m.Add("a", 1)
+	m.Add("z", 2)
+	m2 := NewMap("map2")
+	for i := 0; i < 9; i++ {
+		m2.Add(strconv.Itoa(i), int64(i))
+	}
+	rr := httptest.NewRecorder()
+	rr.Body = new(bytes.Buffer)
+	expvarHandler(rr, nil)
+	want := `{
+"map1": {"a": 1, "z": 2},
+"map2": {"0": 0, "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8}
+}
+`
+	if got := rr.Body.String(); got != want {
+		t.Errorf("HTTP handler wrote:\n%s\nWant:\n%s", got, want)
+	}
+}