每个进程都有它自己的变量的完备集,线程共享相同的数据。---这也是危险之处。
线程创建和销毁的开销都比进程小。---这是好处。
简单的,你只要实现Runnable接口,实现重载run()方法,来做自己想做的事情。然后就是开启一个线程,把你实现的类的对象传入:
Runnable r = new myRunable(args[] a);
Thread t = new Thread(r);
t.start();
这种方法在处理多线程时是不建议的。为每一个线程做的开销是值得权衡的代价。<更好的办法是使用线程池>
线程的stop方法已经废弃。现在可以用interrupt方法来中断一个线程的执行。该方法会对线程的中断状态置位。它是一个布尔变量,存在与每个线程中。每个线程不时地检查这个标示。while(!Thread.currentThread().isInterrupt()&&.....).尽管如此,如果一个线程被阻塞了,它就无法检查中断状态了。这就是产生InterruptedException异常的地方。(interrupted方法会检查当前线程是否中断,该方法会清除该线程的中断状态;isInterrupted方法则不会清除……)
线程的优先级:在不同的宿主机上的虚拟机上,优先级可能依赖与宿主。所以,不要用线程的优先级依赖关系来作为程序功能的实现。
守护线程:唯一的作用就是为其它线程提供服务。当虚拟机中只剩下守护线程时,就没有继续运行程序的必要了。
通过setUncaughtExceptionHandler方法来为线程安装一个未捕获异常处理器。这个处理器的目的就是把异常写入日志。
线程同步:旧版本的JAVA使用Synchronized关键字,5.0以后使用ReentrantLock类来实现代码的保护。
myLock.lock();// a ReentrantLock object
try
{
critical section;
}
finally
{
myLock.unlock();// make sure the lock is unlocked even if an exception is thrown;
}
通常,一个线程进入临界区,发现它必须要满足某个条件后才能执行。要使用一个条件对象来管理那些已经获得锁,却不能开始执行有用工作的线程。
Condition sufficientFunds = banklock.newCondition();
在发现余额不足时,调用sufficientFunds.await();
这样,当前线程被阻塞,且放弃了锁。进入等待该条件集中。
当对该账户存钱后,需要调用sufficientFunds.signalAll();来解除等待线程的阻塞状态。这样,这些线程就可以在当前线程退出同步方法后,通过竞争获得对对象的访问。
JAVA语言中没有任何机制来确保死锁不发生。只能仔细设计自己的程序。
Stop()方法的废弃:是因为这个方法会终止所有未结束的方法包括run方法。当一个线程停止时,它会立即释放所有锁住他的对象上的锁。这会导致对象处于不一致的状态。
suspend方法的废弃:是因为它会引起死锁。(用suspend挂起一个拥有锁的线程,那么锁在恢复之前不会被释放)