一、什么是线程
线程是一个程序的顺序控制流;
二、线程与进程的区别
1)每个进程都有独立的代码和数据空间(进程上下文),进程的切换会有较大的开销;
2)线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有独立的运行栈和程序计数器(PC),线程切换开销小;
3)多进程:在操作系统中能同时运行多个任务(程序);
4)多线程:在同一进程内有多个顺序流执行;
三、线程的状态
线程五态:
详细介绍请参考:https://blog.csdn.net/xingjing1226/article/details/81977129
四、线程优先级
1)记住当线程的优先级没有指定时,所有线程都携带普通优先级。
2)优先级可以用从1到10的范围指定。10表示最高优先级,1表示最低优先级,5是普通优先级。
3)记住优先级最高的线程在执行时被给予优先。但是不能保证线程在启动时就进入运行状态。
4)与在线程池中等待运行机会的线程相比,当前正在运行的线程可能总是拥有更高的优先级。
5)由调度程序决定哪一个线程被执行。
6)t.setPriority()用来设定线程的优先级。
7)记住在线程开始方法被调用之前,线程的优先级应该被设定。
8)你可以使用常量,如MIN_PRIORITY,MAX_PRIORITY,NORM_PRIORITY来设定优先级。
设置优先级代码如下:
public final void setPriority(int i)
{
checkAccess();
if(i > 10 || i < 1)
throw new IllegalArgumentException();
ThreadGroup threadgroup;
if((threadgroup = getThreadGroup()) != null)
{
if(i > threadgroup.getMaxPriority())
i = threadgroup.getMaxPriority();
setPriority0(priority = i);
}
}
五、线程调度
就是对线程分配处理器的使用权。
协同式:一个线程干完活通知系统让另一个线程干活,实现简单;执行时间不受控制,一个线程阻塞,会直接阻塞整个进程。
抢占式:系统分配线程的执行时间,受系统控制。
六、创建线程的多种方式
Java使用Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例。Java可以用四种方式来创建线程,如下所示:
1)继承Thread类创建线程
public class MyThread extends Thread{//继承Thread类
public void run(){
//重写run方法
}
}
public class Main {
public static void main(String[] args){
new MyThread().start();//创建并启动线程
}
}
2)实现Runnable接口创建线程
public class MyThread2 implements Runnable {//实现Runnable接口
public void run(){
//重写run方法
}
}
public class Main {
public static void main(String[] args){
//创建并启动线程
MyThread2 myThread=new MyThread2();
Thread thread=new Thread(myThread);
thread().start();
//或者 new Thread(new MyThread2()).start();
}
}
3)使用Callable和Future创建线程
package com.Higgin.part01;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
class ThirdThread {
}
public class Demo3 {
public static void main(String[] args) {
//创建Callable对象
ThirdThread rt=new ThirdThread();
//先使用Lambda表达式创建Callable<Integer>对象,
//并使用FutureTask来包装Callable对象
FutureTask<Integer> task=new FutureTask<Integer>((Callable<Integer>)()->{
int i=0;
for(;i<1000;i++){
System.out.println(Thread.currentThread().getName()+"===="+i);
}
//call()方法可以有返回值
return i;
});
for(int i=0;i<1000;i++){
System.out.println(Thread.currentThread().getName()+"===="+i);
if(i==20){
Thread t1=new Thread(task,"有返回值的线程");
t1.start();
}
}
try {
System.out.println("子线程的返回值:"+task.get());
} catch (Exception e) {
e.printStackTrace();
}
}
}
4)使用线程池例如用Executor框架
请查看:https://www.cnblogs.com/MOBIN/p/5436482.html
七、守护线程
守护线程(即daemon thread),是个服务线程,准确地来说就是服务其他的线程,这是它的作用——而其他的线程只有一种,那就是用户线程。所以java里线程分2种,
1、守护线程,比如垃圾回收线程,就是最典型的守护线程。
2、用户线程,就是应用程序里的自定义线程。