多线程知识小结

一、线程实现的两种方式

建立Thread实例:(从这个类实例化的一个对象就代表一个线程对象)

4个构造方法:

public Thread()

public Thread ( String threadName )

public Thread( Runnable target )

public Thread ( Runnable target , String name )


1、继承 Thread 类的方式:

public class ThreadTest extends Thread{  ...  }

当一个类继承Thread类后,就可以在该类中覆盖 run() 方法,并将实现线程真正功能的代码放在 run() 方法中,然后调用 Thread类中的 start() 方法执行线程。


2、实现 Runnable 接口:

public class Thread extends Object implements Runnable{ ...  }

建立 Runnable 对象作为参数来构造 Thread 实例,然后调用该实例的 start() 方法启动线程。

【一般常规将Runnable接口的实现类采用匿名内部类的形式作为参数传递给Thread构造函数】


知识点:

1、主方法 main() 启动是由 JVM 负责,程序创建的 Thread 线程对象由程序员通过 start() 方法启动。

2、run() 方法语法格式必须是这样:public void run() { ... }

3、通常在 run() 方法中使用无限循环的形式,使线程一直运行下去,然后在循环中指定循环跳出的条件。

4、启动线程只需调用 start() 方法即可,线程启动后会自动去执行 run() 方法,不能直接调用Thread实例的 run() 方法

4、执行线程需要调用 Thread 类中的 start() 方法,如果不调用 start() 方法,Thread 对象就只是一个实例,而不是一个真正的线程。

5、实际上Thread类也实现了Runnable接口,其run()方法正是对Runnable接口中的run()方法的具体实现。

6、虽然多线程看起来像同时执行,但事实上在同一时间点上只有一个线程被执行。


二、线程的生命周期

7种状态:

出生状态:线程被创建后,调用start() 方法之前的状态

就绪状态:用户调用 start() 方法后的状态

运行状态:线程得到系统资源后进入运行状态


介于就绪和运行之间的4种状态是:

等待状态:线程调用 wait() 方法时,必须调用线程的notify()方法或notifyAll()方法才能被唤醒

休眠状态:线程调用sleep() 方法时

阻塞状态:线程发出输入/输出请求时(即使系统资源空闲,线程依然不能回到运行状态)

死亡状态:线程的run()方法执行完毕时


等待状态和休眠状态都可以被 interrupt() 方法中断


三、操作线程的方法


public static void sleep(long millis) throws InterruptedException

通常在 run() 方法的循环中被使用,它在指定时间内醒来后会再次进入就绪状态


public final void join() throws InterruptedException

当某个线程A使用 join()方法加入到另外一个线程B时,线程B会中断,直到线程A执行完毕才再继续执行


public void interrupt()

该方法调用后,会使线程抛出 InterruptedException 异常,并离开 run() 方法,结束线程(用户也可以在处理该异常时完成线程的中断业务处理,比如中止循环)

【现在提倡在run()方法中使用无限循环的形式,然后使用一个布尔型标记控制循环的停止,从而结束线程的运行】


public static void yield()

给当前正处于运行状态的线程一个提醒,告知它可以将资源礼让给其它线程,但没有任何机制保证当前线程会将资源礼让。


四、线程的优先级

如果有很多线程处于就绪状态,系统会根据优先级决定首先使用哪个线程进入运行状态。并不意味着低优先级的线程得不到运行,只是它运行的机率较小,比如垃圾回收线程的优先级就较低。

Thread.MIN_PRIORITY = 1

Thread.MAX_PRIORITY = 10

Thread.NORM_PRIORITY = 5

线程优先级可以使用setPriority()方法调整,如果设置的优先级不在1~10之内,将产生 IllegalArgumentException 异常。


五、线程同步机制

1、同步块:synchronized(Object) { ... }

通常将共享资源的操作放置在synchronized定义的区域内,这样当其它线程也获取到这个锁时,必须等待锁被释放时才能进入该区域。


Object为任意一个对象,每个对象都存在一个标志位,并具有两个值,分别 为0和1。

一个线程A运行到同步块时首先检查该对象的标志位,如果为0状态,表明此同步块中存在其它线程在运行。

这时A线程处于就绪状态,等待该同步块中的其它线程执行完,并将标志位设置为1,

此时A线程才能执行同步块中的代码,并将Object对象的标志位设置为0,防止其它线程执行同步块中代码。

2、同步方法:synchronized void f() { ... }


当某个对象调用了同步方法时,该对象上的其它同步方法必须等待该同步方法执行完毕才能被执行。

必须将每个能访问共享资源的方法修饰为synchronized,否则就会出错。


猜你喜欢

转载自blog.51cto.com/maplebb/2164966