#多线程学习总结(一):基础知识
最近看了《Java编程多线程核心技术》这本书,在此简单总结下基本知识点:
- 线程和进程的区别
- 线程的使用方法(怎样开启多线程)
- 常用方法
- 线程停止与暂停
- 守护线程
1.进程与线程的区别
**进程:**百度百科对进程的描述如下:
进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。
通俗来讲,操作系统中一个运行中的exe程序就可以看作一个进程,进程是受操作系统管理的基本运行单元。
线程:
2.线程类的定义和线程的开启
线程类的定义方式常见有以下几种
1.继承Thread类,并重写run()方法;
public class ThreadDemo extends Thread{
@Override
public void run() {
//这里面写需要多线程执行的代码段
doSth();
}
}
2.实现Runnable接口
public class ThreadDemo implements Runnable{
@Override
public void run() {
//这里面写需要多线程执行的代码段
doSth();
}
}
与第一种方式相比优势在于可以继承别的类,当你要定义的线程类已经继承了别的父类,就只能采用实现Runnable接口的方式来定义线程类了。
3.其它方法:线程池,lambda表达式等
线程的开启:
以上的代码定义了一个线程类,在测试方法或者main()方法里写
ThreadDemo t1=new ThreadDemo();
t1.start();
这样就开启了一个线程。
注意:1.如果写成了t1.run()并不会开启线程,只会把run()当成普通方法去执行;
2.要开启多个线程的话不能同一个线程对象多次执行start()方法,而要写成下面这种
ThreadDemo t1=new ThreadDemo();
ThreadDemo t2=new ThreadDemo();
ThreadDemo t3=new ThreadDemo();
t1.start();
t2.start();
t3.start();
更优雅的写法是
ThreadDemo t=new ThreadDemo();
Thread t1=new Thread(t);
Thread t2=new Thread(t);
Thread t3=new Thread(t);
t1.start();
t2.start();
t3.start();
三、常用方法
1、currentThread()方法;
Thread类里面的静态方法,该方法返回代码段正在被哪个线程调用的信息。
Thread.currentThread().getName();//返回当前正在执行的线程的名称
Thread.currentThread().getId();//返回当前正在执行的线程的id
2、isAlive()方法;
该方法用来判断当前线程是否处于活动状态。
3.sleep(long millis);
Thread类里面的静态方法,让当前线程休眠指定的毫秒数。
注意该方法不会释放锁(关于锁相关的知识后面会讲解)。
四、线程停止与暂停
虽然加Java提供了以下几个方法来处理线程停止、暂停与继续执行,但最好不要这样写,因为这三个方法都是已过期的方法(@Deprecated),不安全,而且未来可能被弃用。
t1.stop();//线程停止
t1.suspend();//暂停,缺点:独占锁,且数据不同步
t1.resume();//继续执行,缺点同上
Java为我们提供了interrupt()方法来中断线程,
t1.interrupt();//将当前线程的中断状态设置为true
Thread.interrupted();//Thread类里面的静态方法,返回当前线程的中断状态,并将该状态设置为false;
t1.isInterrupted();//返回当前线程的中断状态
线程会在执行完run()方法里的代码之后终止,所以优雅的结束线程的方法应该如下:
public void run(){
while(!this.interrupted()){
//这里面写需要多线程执行的代码段
doSth();
}
//当中断状态为true时跳出循环,线程终止
System.out.println("线程安全的结束");
}
或者把run()方法的方法体包在try-catch语句中,在循环体里面检测到中断状态为true时抛出异常,这样就直接跳到catch里面了,执行完后线程终止;或者检测到中断状态为true时直接return;让线程终止。(建议使用抛异常的方法,让线程停止的事件向上传播)。
五.守护线程
只需要调用setDaemon(true)方法,就可以把一个线程对象设置为守护线程,当且仅当jvm中非守护线程全部结束后,守护线程才会销毁,比如jvm中的垃圾回收线程(GC)就是一个典型的守护线程。
以上所有内容均总结自高洪岩的《Java编程多线程核心技术》一书
系列文章
多线程学习总结(一):基础知识
多线程学习总结(二):同步与并发
多线程学习总结(三):线程间通信
多线程学习总结(四):可重入锁和读写锁