background image

 
// 随机数字生成器

  Random rand;
  // 生成一个随机数字

  Integer id = new Integer(rand.nextInt());
  while (hash.containsKey(id))
  {
  id = new Integer(rand.nextInt());
  }
  // 为当前用户保留该 ID

  hash.put(id, data);

  Listing 1 的代码可能带来一个严重的问题:如果有两个线程执行 Listing 1 的代码,其
中一个线程在 hash.put(...)这行代码之前被重新调度,此时同一个随机 ID 就有可能被使用
两次。在 Java 中,我们有两种方法解决这个问题。首先, Listing 1 的代码可以改写成
Listing 2 的形式,确保只有一个线程能够执行关键代码段,防止线程重新调度,避免竞
争状态的出现。第二,如果前面的代码是 EJB 服务器的一部分,我们最好有一个利用 EJB
服务器线程控制机制的唯一 ID 服务。
  (Listing 2)
  synchronized(hash)
  {
  // 生成一个唯一的随机数字

  Integer id =
  new Integer(rand.nextInt());
  while (hash.containsKey(id))
  {
  id = new Integer(rand.nextInt());
  }
  // 为当前用户保留该 ID

  hash.put(id, data);
  }

  四、字符串解释执行
  在有些编程语言中,输入字符串中可以插入特殊的函数,欺骗服务器使其执行额外
的、多余的动作。下面的 Perl 代码就是一个例子:
  $data = "mail body";
  system("/usr/sbin/sendmail -t $1 < $data");
  显然,这些代码可以作为 CGI 程序的一部分,或者也可以从命令行调用。通常,它可