一个简单的线程例子

来源:互联网 发布:免流服务器ip改域名 编辑:程序博客网 时间:2024/05/22 17:43

SimpleThreads程序有两个线程组成,第一个是主线程,它从创建了一个线程并等待它执行完成。如果MessageLoop线程执行了太长时间,主线程将会将其中断。
MessageLoop现场将会打印一系列的信息。如果中断在它打印完所有信息前发生,它将会打印一个特定的消息并退出。
java 代码

    public class SimpleThreads {          // Display a message, preceded by          // the name of the current thread          static void threadMessage(String message) {              String threadName =                  Thread.currentThread().getName();              System.out.format("%s: %s%n",                                threadName,                                message);          }          private static class MessageLoop              implements Runnable {              public void run() {                  String importantInfo[] = {                      "Mares eat oats",                      "Does eat oats",                      "Little lambs eat ivy",                      "A kid will eat ivy too"                  };                  try {                      for (int i = 0;                           i < importantInfo.length;                           i++) {                          // Pause for 4 seconds                          Thread.sleep(4000);                          // Print a message                          threadMessage(importantInfo[i]);                      }                  } catch (InterruptedException e) {                      threadMessage("I wasn't done!");                  }              }          }          public static void main(String args[])              throws InterruptedException {              // Delay, in milliseconds before              // we interrupt MessageLoop              // thread (default one hour).              long patience = 1000 * 60 * 60;              // If command line argument              // present, gives patience              // in seconds.              if (args.length > 0) {                  try {                      patience = Long.parseLong(args[0]) * 1000;                  } catch (NumberFormatException e) {                      System.err.println("Argument must be an integer.");                      System.exit(1);                  }              }              threadMessage("Starting MessageLoop thread");              long startTime = System.currentTimeMillis();              Thread t = new Thread(new MessageLoop());              t.start();              threadMessage("Waiting for MessageLoop thread to finish");              // loop until MessageLoop              // thread exits              while (t.isAlive()) {                  threadMessage("Still waiting...");                  // Wait maximum of 1 second                  // for MessageLoop thread                  // to finish.                  t.join(1000);                  if (((System.currentTimeMillis() - startTime) > patience)                        && t.isAlive()) {                      threadMessage("Tired of waiting!");                      t.interrupt();                      // Shouldn't be long now                      // -- wait indefinitely                      t.join();                  }              }              threadMessage("Finally!");          }      }  

Java编程语言提供两种同步方式:同步方法和同步语句。
同步方法:
要让一个方法成为同步方法,只需要在方法声明中加上synchronized关键字:

    public class SynchronizedCounter {          private int c = 0;          public synchronized void increment() {              c++;          }          public synchronized void decrement() {              c--;          }          public synchronized int value() {              return c;          }      }  

如果count是SynchronizedCounter类的实例,那么让这些方法成为同步方法有两个作用:
首先,相同对象上的同步方法的两次调用,它们要交替执行是不可能的。 当一个线程正在执行对象的同步方法时,所有其他调用该对象同步方法的线程会被阻塞(挂起执行),直到第一个线程处理完该对象。

其次,当一个同步方法退出时,它会自动跟该对象同步方法的任意后续调用建立起一种happens-before关系。这确保对象状态的改变对所有线程是可见的。

注意构造方法不能是同步的——构造方法加synchronized关键字会报语法错误。同步的构造方法没有意义,因为当这个对象被创建的时候,只有创建对象的线程能访问它。

警告:当创建的对象会被多个线程共享时必须非常小心,对象的引用不要过早“暴露”出去。比如,假设你要维护一个叫instances的List,它包含类的每一个实例对象。你可能会尝试在构造方法中加这样一行:

    instances.add(this);  

死锁
死锁描述了这样一种情景,两个或多个线程永久阻塞,互相等待对方释放资源。下面是一个例子。

Alphone和Gaston是朋友,都很讲究礼节。礼节有一个严格的规矩,当你向一个朋友鞠躬时,你必须保持鞠躬的姿势,直到你的朋友有机会回鞠给你。不幸的是,这个规矩没有算上两个朋友相互同时鞠躬的可能。

下面的应用例子,DeadLock,模拟了这个可能性。

static class Friend {          private final String name;          public Friend(String name) {              this.name = name;          }          public String getName() {              return this.name;          }          public synchronized void bow(Friend bower) {              System.out.format("%s: %s"                  + "  has bowed to me!%n",                  this.name, bower.getName());              bower.bowBack(this);          }          public synchronized void bowBack(Friend bower) {              System.out.format("%s: %s"                  + " has bowed back to me!%n",                  this.name, bower.getName());          }      }      public static void main(String[] args) {          final Friend alphonse =              new Friend("Alphonse");          final Friend gaston =              new Friend("Gaston");          new Thread(new Runnable() {              public void run() { alphonse.bow(gaston); }          }).start();          new Thread(new Runnable() {              public void run() { gaston.bow(alphonse); }          }).start();      }  }  

http://www.iteye.com/magazines/131-Java-Concurrency 原文链接

0 0
原创粉丝点击