Java 学习:多线程
线程
Java 给多线程编程提供了内置的支持。 一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
创建线程:
Java 提供了三种创建线程的方法:
- 通过实现 Runnable 接口;
- 通过继承 Thread 类本身;
- 通过 Callable 和 Future 创建线程。
通过实现 Runnable 接口创建线程:
public class Demo{
public static void main(String[] args) {
//创建实现了Runable接口的任务对象
Test1 t = new Test1();
//创建线程将任务对象作为Thread的构造参数交给线程
Thread thread = new Thread(t);
//调用线程的start方法开启线程,JVM会自动调用任务对象的run方法执行任务
thread.start();
}
}
/**
*创建线程1 通过实现 Runnable 接口;
*/
class Test1 implements Runnable{
/**
* 实现Runnable接口的run方法
*/
@Override
public void run() {
//这里是线程要执行的任务
System.out.println("任务执行...");
}
}
通过继承 Thread 类本身创建线程:
public class Demo {
public static void main(String[] args) {
//创建继承了Thread类的t对象
Test2 t = new Test2();
//调用start方法开启线程,JVM会自动调用run方法执行任务
t.start();
}
}
/**
* 创建线程2 通过继承 Thread 类
*/
class Test2 extends Thread{
/**
* 重写Thread类的run方法
*/
@Override
public void run() {
//这里是线程要执行的任务
System.out.println("任务执行...");
}
}
通过 Callable 和 Future 创建线程:
public class Demo {
public static void main(String[] args) {
//创建实现了Callable接口的对象
Test3 t = new Test3();
//创建FutureTask对象, 将实现了Callable接口的对象作为构造参数传给FutureTask
FutureTask futureTask = new FutureTask(t);
//创建Thread对象,将创建好的FutureTask对象作为构造参数传给Thread,并调用start方法开启线程
new Thread(futureTask).start();
try {
//可以通过futureTask对象的get方法获取线程执行的返回值
Object o = futureTask.get();
System.out.println("返回的对象=》 " + o);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
/**
* 创建线程3 通过实现 Callable接口
*/
class Test3 implements Callable {
/**
* 实现Callable接口的call方法
*/
@Override
public Object call() throws Exception {
//这里是线程要执行的任务
System.out.println("任务执行...");
//返回自己要返回的对象
return new Object();
}
}
线程的相关API:
-
Thread.currentThread().getName() //Thread的静态方法,获取当前线程的名字
-
Thread.currentThread() //Thread静态方法,返回执行当前代码的线程
-
Thread.yield() //Thread的静态方法,主动释放当前线程的执行权
-
Thread.sleep(long millitime) //Thread的静态方法,让当前线程休眠指定时间
-
void start() //启动当前线程
-
String getName() //获取线程的名字
-
void setName() //设置线程的名字
-
void join() //在线程中插入执行另一个线程,该线程被阻塞,直到插入执行的线程完全执行完毕以后,该线程才继续执行下去
-
void isAlive() //判断线程是否存活
-
int getPriority() //获取线程的优先级别
-
void setPriority(int newPriority) //设置线程的优先级为newPriority
-
void void setDaemon(boolean on) //将线程设置是否为守护线程,参数true守护,false不守护
-
void interrupt() //中断线程
线程的分类:
java中的线程分为两类:
守护线程:如垃圾回收,异常处理都是守护类型的线程
户用线程:如主线程,或是程序员创建的线程
注意:当JVM中用户线程全部执行完,不管守护线程是否还有未执行完的,程序都将结束,JVM将退出。
线程的调度:
调度策略:
时间片:线程的调度采用时间片轮转的方式
抢占式:线程优先级高的会抢占CPU
Java的调度方法:
- 对相同优先级的线程组成先进先出队列,使用时间片策略
- 对优先级高的线程,使用优先调度的抢占式策略
注意:优先级高的线程要抢占优先级低的线程的CPU的执行权。但仅从概率上来说的,优先级高的更有可能被执行,并不意味着只有优先级高的执行完以后才去执行优先级低的。
线程的优先级:
在Thread类内定义了MIN_PRIORITY=1、NORM_PRIORITY=5、MAX_PRIORITY=10三个级别,一半线程优先级默认是NORM_PRIORITY
并发并行:
并发:一个CPU(采用时间片)同时执行多个任务。
并行:多个CPU同时执行多个任务。
文连接,否则保留追究法律责任的权利。