在Java中,为了生成一个线程,有两种方法:

  1. 继承Thread类,覆盖run方法。在使用时,调用Thread实例的start方法即可启动一个线程,此线程将执行run方法里面的代码。
  2. 实现Runnable接口,实现run方法。在使用时,调用Thread实例(传入实现Runnable接口的类实例)的start方法,此线程将执行run方法里面的代码。

启动线程的方法只能用start方法,不能用run方法...start方法才会启动一个线程去执行run方法,而run方法仅仅是一个类实例的方法!!!

在此,需要强调的是,线程和Thread类的区别。线程是一个动态的概念,而Thread类(或其实例)是静态的概念。虽然说从代码上看,执行Thread实例的start方法或者run方法(只能在实现Runnable接口时)好像把Thread实例当作了一个线程,当事实上,应该这样理解:Thread类就是一个普通的类,和其他类没有什么两样,但是他的start方法或者run方法比较特殊,可以启动一个新的线程。当新线程启动后,就马上执行Thread类里面run方法的代码或者Runnable接口的run方法。 在Java中,为了实现多线程之间的同步和互斥,提供了一个关键字,synchronized。这个关键字有两个用法:

  1. 用于方法声明中。如: public synchronized void methd(){ .... } 把这种用法称之为synchronized方法。
  2. 用于方法体中。如: public void method(){ synchronized(this){ .... } }把这种方法称为synchronized语句。

当不同的线程运行synchronized方法或者synchronized语句时,首先会获得锁,然后再执行,当退出时,会释放锁。当锁还没有被释放时,如果有其他线程访问,那么这些线程会阻塞。如果锁被释放,那么jvm会让所有在此锁上阻塞的所有线程竞争,将有一个线程得到锁,其他线程将继续阻塞。 其实,synchronized方法就是在方法体的最前面加了一个锁,在方法体的最后面释放掉了这个锁。synchronized语句就是在被包含的语句 前加了一个锁,在被包含的语句后释放掉了锁。这里需要强调锁的概念,可以这么认为,Java中每一个对象都有一个锁的,可以使用synchronized 方法和synchronized语句来获得这些锁。 下面通过实例来理解synchronized方法和synchronized语句。 1,下面的两个方法是等价的: public synchronized void methd(){ .... } public void method(){ synchronized(this){ .... } } 怎么理解上面的等价? synchronized方法(只能)获得当前对象的锁,那么,在synchronized语句中显示的指明要获得锁的对象为this就可以使两者等价了。 在synchronized方法中,多个线程同时只能访问某个对象(可能含多个synchronized方法)的一个synchonized方法。 对下面这个银行类来说,使用synchronized方法就可以达到线程的互斥。多个线程同时只能有一个线程访问一个synchronized方法。 public class Bank{ public synchronized void deposite(){ 对某个帐户进行增加 } public synchronized void withdraw(){ 对某个帐户进行减少 } } 如果,我们想对某个对象的方法进行更灵活的线程互斥访问,可以使用synchornized语句,显示的声明要获得的锁的对象。 2, public synchronized static  void methd(){ .... } 上面的方法都可以防止多个线程同时访问这个类中的method方法。它可以对类的所有对象实例起作用。他等价于下面的方法。 public static  void method(){ synchronized(this.getClass()){ .... } } 这里还需要补充一下,synchronized方法被继承后就不是synchronized的了,除非在子类中再次声明方法为synchronized的。 Object类是Java所有对象的基类,Object类中有几个方法,提供了对多线程编程的支持:

  1. wait()方法将当前运行的线程阻塞,放置于当前线程锁执行的对象的wait set中,然后取消此线程对锁的获得。
  2. notify()/notifyAll()方法将把当前线程执行的对象的wait set中的某一个/所有线程拿出来。

注意,wait和notify/notifyAll方法只能在线程已获得对象实例的锁时才能调用,否则,将抛出java.lang.IllegalMonitorStateException。 这篇文章写的好累啊,语言组织能力咋这么弱...


文章来源:http://localhost/wp2/?p=52