一、线程的创建
java中创建线程有两种方式:继承Thread类和实现Runnable接口。
1.继承Thread类
Java语言中定义了线程类Thread,用户可以通过继承Thread类,覆盖其run()方法创建自己的线程类,线程执行的代码都包含在run方法中。
public ClassName extends Thread{
public void run(){
}
}
2.实现Runnable接口
另一种线程的实现方式是实现Runnable接口。如果自定义的线程还要继承其他类,这时就不能采用第一种方式来创建,java语言是不支持多继承的,却可以实现多个接口,线程同样要实现Runnable接口中的run方法,线程需要执行的代码都包含在run方法中。
Class MyThread implements Runnable{
public void run(){
}
}
二、线程的启动
继承Thread类方式的线程启动非常简单,只要创建线程类实例后调用其start()方法用来完成线程的启动。
ClassName c = new ClassName();
c.start();
实现Runnable接口创建的线程首先转换为Thread类,然后调用Thread类的start()方法启动线程。
MyThread mt = new MyThread();
Thread t = new Thread(mt);
t.start();
三、线程的生命周期
一个生命周期内的线程主要包括创建、就绪、运行、阻塞和死亡状态。
1.创建:在线程类使用new关键字实例化之后在调用start()方法之前,线程处于创建状态。处于创建状态的线程仅仅分配了内存空间,属于生命周期的初始状态。
2.就绪:在线程调用了start()方法后即处于就绪状态。处于就绪状态的线程具备了除CPU之外运行所需的所有资源。就绪状态线程排队等待CPU,由系统调度为其分配。
3.运行:处于就绪状态的线程获得CPU之后即处于运行状态。处于运行状态的线程才开始正真执行线程run()方法的内容。
4.阻塞:处于运行状态的线程如果因为某种原因不能继续执行,则进入阻塞状态。阻塞状态与就绪状态不同的是:就绪状态只是因为缺少CPU而不能执行,而阻塞状态是由于各种原因引起线程不能执行,不仅仅是缺少CPU。引起阻塞的原因解除之后,线程再次转化为就绪状态。
5.死亡:当线程执行完run()方法的内容或被强制终止时,线程处于死亡状态,整个生命周期结束。
四、线程的调度
1.线程的优先级:在java语言中,通过调用setPriority()方法为线程设置优先级,优先级用1~10的数字表示,数字越大,优先级越高。如:c.setPriority(1),接着再启动线程。
2.线程休眠:对于正在执行的线程,可以调用sleep()方法使其放弃CPU进行休眠,此线程转为阻塞状态,sleep()方法包含long型的参数,用于指定线程休眠的时间,单位为毫秒。
3.线程让步:对于正在执行的线程,可以调用yield方法使其重新排队,将CPU让给排在后面的线程,此线程转为就绪状态。yield()方法只让步给高优先级或同等优先级的线程。
4.线程等待:对于正在执行的线程,可以调用join()方法等待其结束,然后才执行其他程序。
如:c.start();
c.join();
t.start;
等待c线程执行完成再执行t.
五、线程同步
当多个线程操作同一个共享资源时,比如读写同一个变量,存在着资源竞争的问题。为了解决此类问题,需要使用同步机制。在java语言中,利用synchronized关键字实现线程同步。
实例如下:
class MyThread implements Runnable{
private int con = 0;
@Override
public void run() {
test();
}
private void test(){
for(int i = 0;i<10;i++){
con++;
Thread.yield();
con--;
System.out.println(con);
}
}
}
public class testThread {
public static void main(String[] args) {
MyThread t = new MyThread();
Thread t1 = new Thread(t);
Thread t2= new Thread(t);
t1.start();
t2.start();
}
}
结果如下:
0
0
0
0
0
0
1
0
0
1
0
1
调整如下:
class MyThread implements Runnable{
private int con = 0;
@Override
public void run() {
test();
}
private synchronized void test(){
for(int i = 0;i<10;i++){
con++;
Thread.yield();
con--;
System.out.println(con);
}
}
}
public class testThread {
public static void main(String[] args) {
MyThread t = new MyThread();
Thread t1 = new Thread(t);
Thread t2= new Thread(t);
t1.start();
t2.start();
}
}
输出的结果全为0.