http://www.ibm.com/developerworks/cn/java/j-thread/index.html
http://www.ibm.com/developerworks/cn/java/multithreading/index.html
http://www.ibm.com/developerworks/cn/education/java/j-threads/j-threads.html
线程的概念基本清楚, 关键是访问共享变量时, 一定要注意.
volatile: 对于简单变量, 使用 volatile 关键字就够了, 表示同步变量, 在多个线程中访问了 volatile时, 必须保证所有访问该变量的地方都使用了同步. 这个还是很有用的, 比如你开启了100个线程, 都在跑着, 而你想通过一个标记变量来关闭这些线程, 那么这个变量就可以实现.
线程的创建, 要么 extends Thread, 要么 实现 Runnable 接口
1. 通过继承 Thread 创建线程
2. 通过 Runnable 接口创建线程
此接口只有一个函数,run(),此函数必须由实现了此接口的类实现。但是,就运行这个类而论,其语义与前一个示例稍有不同, 我们可以用runnable 接口改写前一个示例。(不同的部分用黑体表示。)
请注意,当使用 runnable接口时,您不能直接创建所需类的对象并运行它;必须从 Thread类的一个实例内部运行它。许多程序员更喜欢runnable 接口,因为从Thread 类继承会强加类层次.
线程的启动, start()
线程的结束, run() 执行完了, 或者 抛出异常, 或者 另一个线程调用一个弃用的 stop() 方法. (stop方法已经不提倡使用)
加入线程, join()方法, 当调用 Thread.join()
时,调用线程将阻塞,直到目标线程完成为止。
休眠, 当前线程进入等待状态, sleep()方法, 直到过了一段时间, 或者 另一个线程对当前线程的 Thread 对象调用了 interrupt() 方法, 从而终端了这个等待的线程, 如果线程是由对 Thread.interrupt()的调用而终端的, 那么休眠的线程会抛出 InterruptedException, 这样线程就知道它是由中断唤醒的,就不必查看计时器是否过期.
Thread.yield() 同 sleep 一样, 它并不引起休眠,而只是暂停当前线程片刻,这样其它线程就可以运行了, 在大多数实现中,当较高优先级的线程调用 Thread.yield()
时,较低优先级的线程就不会运行.
同步: Synchronized
有两个重要含义:它确保了一次只有一个线程可以执行代码的受保护部分, 而且它确保了一个线程更改的数据对于其它线程是可见的.
锁: 每个 Java 对象都有一个相关的锁。同一时间只能有一个线程持有 Java 锁。当线程进入 synchronized
代码块时,线程会阻塞并等待,直到锁可用,当它可用时,就会获得这个锁,然后执行代码块.当控制退出受保护的代码块时, 即到达了代码块末尾或者抛出了没有在 synchronized块中捕获的异常时,它就会释放该锁。
创建 synchronized
块的最简单方法是将方法声明成 synchronized
。这表示在进入方法主体之前,调用者必须获得锁:
在某些情况中,您不必用同步来将数据从一个线程传递到另一个,因为 JVM 已经隐含地为您执行同步。这些情况包括:
static{}
块中的初始化器)初始化数据时