目录
多线程简介
Java 给多线程编程提供了内置的支持。 一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
进程中的一个执行控制单元,也叫执行路径,一个进程可以有一个线程,也可以有多个线程
单线程 安全性高 效率低 多线程 安全性低 效率高
多线程实现方式
1. 继承Thread
2. 实现Runable
3. 实现Callable
一 创建执行线程的三个方式 : 实现Callable接口。 相较于实现Runable接口的方式,方法可以有返回值,并且可以抛出异常
二 执行Callable方式,需要FutureTask实现类的支持,用于接收运算结果
注意:get方法是阻塞的,即:线程无返回结果,get方法会一直等待
继承Thread
public class Demo {
public static void main(String[] args) {
//创建线程变量
T1 t1 = new T1();
T2 t2 = new T2();
// t1.start();//启动线程
// t2.start();
//不能用run启动线程 否则将变成从上往下 先执行完t1在执行t2
// t1.run();
// t2.run();
}
}
class T1 extends Thread{
public void run(){ //线程执行的任务
for (int i=0; i<1000; i++){
System.out.println("你是谁啊");
}
}
}
class T2 extends Thread{
public void run(){
for (int i=0; i<1000; i++){
System.out.println("我是T2");
}
}
}
实现Runable
public class Demo {
public static void main(String[] args) {
//创建一个线程要执行的任务
// T t = new T();
//创建线程
Thread T = new Thread(new T()/* t */);//把要执行的任务放到构造器里面
//启动线程
T.start();
}
}
//Runable 相当于我们创建的一个任务 是线程要执行的任务
class T implements Runnable{
public void run(){
System.out.println("实现Runable");
}
}
实现Callable
public class Demo {
public static void main(String[] args) {
CallableTest ct = new CallableTest();
FutureTask<String> task = new FutureTask(ct);
task.run();
try {
//是一个阻塞方法,等着线程执行完返回结构 才阻塞结果
String st = task.get();//返回任务执行的结构
System.out.println("==="+st);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
//线程要执行的任务
class CallableTest implements Callable<String>{
@Override
//可以存在返回值 可以处理异常
public String call() throws Exception {
System.out.println("任务开始了。。。。。");
Thread.sleep(3000);
return "abc";
}
}
线程优先级
线程的优先级不是代表必须先执行,只是执行的几率大大增加。
public class Demo{
public static void main(String[] args) {
Thread t1 = new Thread("张三"){ //用有参数构造器来给线程设置一个名字
public void run(){
System.out.println("线程1"+Thread.currentThread());
}
};
Thread t2 = new Thread("李四"){
public void run(){
System.out.println("线程2");
}
};
//优先级是指获取时间片段的能力 但是优先级高的不一定先执行 只是获取时间片段的几率大
//1是最低优先级 10是最高优先级 5是默认
//设置线程优先级 注意设置线程属性的时候一定要在线程启动前
t1.setPriority(1);
t2.setPriority(10);
t1.start();
t2.start();
}
}
多线程的一些方法
public class Demo{
public static void main(String[] args) {
System.out.println(Thread.currentThread());//Thread[main,5,main] 线程名字 优先级 组
System.out.println("--------------------");
//匿名内部类 === 继承Thread类
Thread t = new Thread(){
public void run(){
Thread thread = Thread.currentThread(); //返回当前线程
//long id = main.getId(); 获取线程的ID
System.out.println(thread.getId());
//String name = main.getName(); 获取线程的名字
System.out.println(thread.getName());
//int priority = main.getPriority(); 获取线程的优先级
System.out.println(thread.getPriority());
//boolean isAlive = main.isAlive(); 线程是否处于活动状态
System.out.println(thread.isAlive());
//boolean isDaemon = main.isDaemon(); 是否为线程守护
System.out.println(thread.isDaemon());
//boolean isInterrupted = main.isInterrupted 是否被中断
//指的是睡眠阻塞被中断
System.out.println(thread.isInterrupted());
//thread.interrupt(); 中断睡眠阻塞
}
};
t.start();
}
}
睡眠阻塞
类似于一次性定时器,当程序运行时,遇到阻塞,会停止当前进程,等待规定时间结束,在继续运行。
public class Demo05 {
public static void main(String[] args) {
//睡眠阻塞
Thread t1 = new Thread(){
public void run() {
for (int i=0; i<100; i++){
try {
Thread.sleep(1000); //1000毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("我是刘德华");
}
}
};
t1.start();
}
}
join方法
常被用调协线程之间同步运行使用,该方法会让调用这个方法的线程处于阻塞状态,直到该方法所属的线程结束,才会取消阻塞线程的阻塞状态
同步运行:运行有先后顺序
异步执行:运行没有先后顺序,各执行各的。