线程是每一个java开发工程师,必须了解的常识,那么对于线程又如何学习,从哪里学习呢?下面就一一开始介绍和学习
一,线程的生命的周期
每一个线程都是有生命周期的,一般来说,线程是分为五种状态的。
① NEW(新建状态):当一个线程被new 出来的时候就是新建状态。
Thread thread = new Thread()
② Runnable(就绪状态) : 调用该对象的.start()方法,就可以启动该线程。一般处于就绪状态的线程,随时可能被CPU调用
thread .start()
③ Running(运行状态) : CPU进行掉用此线程开始执行,线程里面的逻辑。这个状态,只能从就绪状态进入运行状态,其他状态没有办法到运行状态。
④ Blocked(阻塞状态) :这种情况就是因为某些原因,暂时停止运行,这种状态如果想继续运行,那么就需要进入就绪状态才能转到运行状态。
⑤ Dead(死亡状态) : 线程完成自己的使命或者因为异常而结束生命周期。
二,实现线程的方式
这里介绍两种实现方式
第一种方式 FirstThread 是通过实现 Runnable接口
第一种方式 SecondThread 是通过继承 Thread类
以下是代码实现测试多线程的类
/**
*这是测试类
*/
public class ThreadTest {
public static void main (String[] args) throws InterruptedException {
/**
* 第一种方式 FirstThread 是通过实现 Runnable接口
* 第一种方式 SecondThread 是通过继承 Thread类
*/
FirstThread firstThread =new FirstThread();
SecondThread secondThread =new SecondThread();
/**
* new出两个子线程,将两个对象放进子线程中进行运行
*/
Thread runnableThread = new Thread(firstThread);
Thread threadThread = new Thread(secondThread);
/**
* 通过使用线程的.start()方法进行运行子线程
*/
threadThread.start();
runnableThread.start();
Thread.sleep(5000);
System.out.println("主线程开始运行");
}
}
以下是第一种方式:实现Runnable接口
/**
* 第一种方式:实现Runnable接口
* <p>
* </p>
* @author libing
* @since 2019-03-05 下午 10:29
*/
public class FirstThread implements Runnable {
@Override
public void run() {
System.out.println("实现Runnable接口线程:火车票出售ing...");
}
}
下面是第二种方式:继承 Thread类
/**
* 第一种方式:继承Thread类
* <p>
* </p>
*
* @author libing
* @since 2019-03-05 下午 10:30
*/
public class SecondThread extends Thread {
@Override
public void run() {
super.run();
System.out.println("继承Thread类子线程:火车出售ing...");
}
}
注意: 将继承Thread或者实现Runnable接口,放在new出来的线程运行,切记一定要使用.start()方法,将线程从新建状态变成运行状态
另外,在源码中我们可以轻易的看到,Thread类其实也是实现了Runable接口。
通常,建议通过“Runnable”实现多线程!
三,Thread中start()和run()的区别
.start() : 它的作用是启动一个新的线程,当启动新线程后,会默认调用响应的run()方法。
注意:start()不可以被重复调用,重复启动会报错。
run() : run()就和普通的成员方法一样,可以被重复调用。单独调用run()的话,会在当前线程中执行run(),而并不会启动新线程!
四,synchronized关键字
我们将synchronized的基本规则总结为下面3条,并通过实例对它们进行说明。
第一条: 当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时,其他线程对“该对象”的该“synchronized方法”或者“synchronized代码块”的访问将被阻塞。
第二条: 当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时,其他线程仍然可以访问“该对象”的非同步代码块。
第三条: 当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时,其他线程对“该对象”的其他的“synchronized方法”或者“synchronized代码块”的访问将被阻塞。