什么是线程
是指从软件或者硬件上实现多个线程并发执行的技术。 具有多线程能力的计算机因有硬件支持而能够在同一时间执 行多个线程,提升性能。并发和并行
并行:在同一时刻,有多个指令在多个CPU上同时执行并发:在同一时刻,有多个指令在单个CPU上交替执行
进程和线程
进程是正在运行的程序独立性:进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位
动态性:进程的实质 是程序的一次执行过程,进程是动态产生,动态消亡的
并发性:任何进程都可以同其他进程一起并发执行
线程是进程中的单个顺序控制流,是一条执行路径
单线程:一个进程如果只有一条执行路径,则称为单线程程序
多线程:一个进程如果有多条执行路径,则称为多线程程序
实现多线程的方式
方式一:继承Thread类
方法名 | 方法名 |
---|---|
void run() | 在线程开启后,此方法将被调用执行 |
void start() | 使此线程开始执行,Java虚拟机会调用run方法() |
1、定义一个类继承Thread类
2、在类中重写run()方法
3、创建该类的对象
4、启动线程
示例代码
public class MyThread extend Thread{
/*
重写run()是因为该方法是用来封装被线程执行的代码
run()和start()方法的区别
run():封装线程执行的代码,直接调用,相当于普通方法的调用
start():启动线程,然后由jvm调用此线程的run()方法
*/
@Override
public void run(){
System.out.println("hello");
}
}
public class MyThreadDemo{
public static void main(String[] args){
MyThread mt = new MyThread();
mt.start();
}
}
方式二:实现Runnable接口
方法名 | 方法名 |
---|---|
Thread(Runnable target) | 分配一个新的Thread对象 |
Thread(Runnable target, String name) | 分配一个新的Thread对象 |
1、定义一个类实现Runnable接口
2、在该类中重写run()方法
3、创建该类对象
4、创建Thread类对象,把该类对象作为构造方法的参数
5、启动线程
示例代码
public class MyThread implement Runnable{
@Override
public void run(){
System.out.println("hello");
}
}
public class MyThreadDemo{
public static void main(String[] args){
MyThread mt = new MyThread();
Thread t = new Thread(mt);
t.start();
}
}
方式三:实现Callable接口
方法名 | 方法名 |
---|---|
V call() | 计算结果,如果无法计算结果,则抛出一个异常 |
FutureTask(Callable callable) | 创建一个 FutureTask,一旦运行就执行给定的 Callable |
V get() | 如有必要,等待计算完成,然后获取其结果 |
1、定义一个类实现Callable接口
2、在该类中重写call()方法
3、创建该类对象
4、创建Future的实现类FutureTask对象,把我们创建的类的对象作为构造方法的参数
5、创建Thread对象,把FutureTask对象作为构造方法的参数
6、启动线程
7、再调用get方法获取结果
示例代码
public class MyThread implement Callable<String>{
@Override
public String call() throws Exception{
return "hello";
}
}
public class MyThreadDemo{
public static void main(String[] args){
MyThread mt = new MyThread();
FutureTask<String> ft = new FutureTask<>();
Thread t = new Thread(ft);
String str = ft.get();
t.start();
System.out.println(str);
}
}
三种方法的优缺点
实现Runnable、Callable接口好处:扩展性强,实现该接口的同时还可以继承其他的类
缺点:编程相对复杂,不能直接使用Thread类中的方法
继承Thread类
好处: 编程比较简单,可以直接使用Thread类中的方法
缺点: 可以扩展性较差,不能再继承其他的类
设置和获取线程名称
方法名 | 说明 |
---|---|
void setName(String name) | 将此线程的名称更改为等于参数name |
String getName() | 返回此线程的名称 |
Thread currentThread() | 返回对当前正在执行的线程对象的引用 |
示例代码
public class MyThread extend Thread{
public MyThread(){}
public MyThread(String name){
super(name)
}
@Override
public void run(){
for(int i = 0;i < 100;i++){
System.out.println(getName()+":"+i);
}
}
}
public class MyThreadDemo{
public static void main(String[] args){
MyThread mt1 = new MyThread();
MyThread mt2 = new MyThread();
mt1.setName("A");
mt2.setName("B");
mt1.start();
mt2.start();
System.out.println(Thread.currentThread().getName())
}
}
线程休眠
方法名 | 说明 |
---|---|
static void sleep(long millis) | 使当前正在执行的线程停留(暂停执行)指定的毫秒数 |
public class MyThread implement Runnable{
@Override
public void run(){
for(int i = 0;i < 100;i++){
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"=="+i)
}
}
}
public class MyThreadDemo{
public static void main(String[] args){
MyThread mt = new MyThread();
Thread t1 = new Thread(mt);
Thread t2 = new Thread(mt);
t1.start();
t2.start
}
}