目录
1.进程和线程
进程是计算机正在运行的一个独立的应用程序,进程是一个动态的概念,必须是运行状态,如果一个应用程序没有启动,那就不是一个进程。
线程就是组成进程的基本单位,可以完成特定的功能,一个进程是由一个或者多个线程组成
1.1进程和线程区别:
内存空间 | 安全性 | |
进程 | 有独立空间 | 进程安全 |
线程 | 有共享空间,也有独立空间 | 线程安全性差 |
1.1.1内存空间的区别:
- 进程是有独立空间的,在线程创建时就会分配的空间(例如:堆 ),每个进程的空间是相互独立的,互不影响
- 线程有共享的空间,也有独立的空间。堆空间:线程共有;虚拟机栈:线程私有
1.1.2线程安全性:
- 进程之间是相互独立的,一个进程的奔溃不会影响其他进程,进程之间是安全的
- 线程之间存在内存共享,一个线程的奔溃可能会影响到其他的线程执行,线程的安全性不如进程
java中很少使用到进程概念,但也可以使用Runtime.getRuntime() --->启动一个进程
2.线程的创建
-
实现Runable接口
-
继承Thread类
-
实现Callable接口
2.1实现Runable接口
runnable接口声明形式如下:
public interface Runnable {
public abstract void run();
}
runnable接口中提供了一个run抽象方法,所有新创建的线程要执行的业务逻辑在run方法中实现
创建一个runnable接口的实现类:
public class Runable212 implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " 子线程正在执行" + i);
}
}
通过runnable接口来实现线程调用
//创建一个Runnable的任务体实例
Runable212 runable212 = new Runable212();
//创建一个线程实例来执行任务体
Thread thread = new Thread(runable212);
//启动子线程
thread.start();
通过Runable接口来创建多线程:
1、实现一个Runnable接口的实现类,在给类中将子线程的业务就在run方法中实现
2、实例化一个Runable的实例
3、创建Thread类实例,将实例化的Runable对象作为参数传递
4、启动子线程,调用thread对象的start方法
线程的创建也可以通过匿名内部类的形式来创建,实现Runable接口的方式
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " 子线程....");
}
}).start();
2.2继承Thread类
Thread类定义:
public class Thread implements Runnable
Thread类是实现了Runnable接口,即Thread类也是Runable接口的实现类
在Thread中run方法的实现如下:
@Override
public void run() {
if (target != null) {
target.run();
}
}
在子线程中需要实现自定义的业务,通过继承Thread类时就需要重写run方法
继承Thread类:
public class Thread212 extends Thread {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" 子线程正在执行...");
}
}
//创建出Thread类的实例
Thread212 thread212 = new Thread212();
//启动子线程
thread212.start();
通过继承Thread类来创建子线程步骤:
1、创建类:继承自Thread(extend Thread) ,重写run方法
2、实例化自定义的Thread的子类
3、启动子线程
2.3实现Callable方法
Callable接口声明如下:
public interface Callable<V> {
V call() throws Exception;
}
Callable接口提供了call方法,方法具有返回值,通过泛型类定义的,且可以抛出异常。该接口的实现类无法直接使用,所以需要借助Futureask类
FutureTask类声明如下:
public class FutureTask<V> implements RunnableFuture<V>
public interface RunnableFuture<V> extends Runnable, Future<V> {
void run();
}
FutureTask是可以接口Callable的接口,FutureTask类是实现自RunnableFuture接口,而RunnableFuture接口是继承自Runable接口,则意味着该FutureTask类的实例即是Runnable的实例,可以作为参数传递给Thread
实现callable接口的实现类:
public class Callable212 implements Callable<String> {
@Override
public String call() throws Exception {
String name = Thread.currentThread().getName();//获得当前线程的名字
System.out.println(name+" 子线程正在执行...");
return name;
}
}
通过Callable接口来创建子线程
//实例化一个Callable接口的实现类
Callable212 callable212 = new Callable212();
//实例化一个FutureTask实例,并传入callable对象实例
FutureTask <String> futureTask = new FutureTask <>(callable212);
//实例化Thread对象,将futureTask实例对象传入(本质上是Runable的实例)
Thread thread = new Thread(futureTask);
//启动子线程
thread.start();
通过Callable接口来创建子线程步骤:
1、实现一个Callable接口的实现类,实现call方法
2、实例化一个Callable的实例对象
3、创建一个FutureTask类型的对象实例,并传入Callable的实例对象
4、创建Thread的实例,将FutureTask实例对象传入
5、启动子线程
学习时候的学习总结,如果有错误,欢迎指正哈~