多线程意味着快速的去抢占对应资源,在大部分场景是多核CPU的今天,去用于提升代码响应速度是一种很好的方式。有利必有弊,资源的安全性和可操作性是使用多线程时最应考虑到的事。
线程和进程的再熟悉
1、进程:
老生常谈属于是,什么是进程——运行中的程序,有单独进程号的-pid。进程的三个状态:
(1)动态性:进程是运行中的程序,要动态的去占用内存,CPU和网络资源
(2)独立性:进程与进程之间是相互独立的,占用各自的内存空间
(3)并发性:假如CPU是单核的,那么某一个具体时刻只有一个进程在运行 - 达到并行的目的,显示为同一时刻多个进程在运行
2、线程:
什么是线程,线程是属于进行的,进程中包含各单元子模块,各单元子模块共同构建起进程功能。多个线程存在的唯一目的就是抢占资源然后完成自己的任务——线程是自私的。
线程的创建
线程的创建方式有三种,分别是继承Thread,实现Runable,实现Callable,接下来分别阐述具体的对应实现以及各自优势
1、继承Thread类去进行创建
public class ThreadDem_one {
public static void main(String[] args) {
ThreadRun threadRun = new ThreadRun("xue");
threadRun.start();
System.out.println(threadRun.getName());
//main与子线程是并发执行的——推进的——因此在执行过程中会出现随机性
for (int i = 0; i < 10; i++) {
System.out.println("主线程运行中:" + i);
}
}
}
class ThreadRun extends Thread{
//使用构造器 - 直接使用名称去对线程进行构造 - 创造出线程名称特定的线程
public ThreadRun(String name){
super(name);
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("子线程运行中" + i);
}
}
}
注:继承减小了可扩展性——是劣势我认为
2、实现runable方式去进行创建
public static void main(String[] args) {
MyRunAble myRunAble = new MyRunAble();
Thread thread = new Thread(myRunAble, "xue");
thread.start();
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
class MyRunAble implements Runnable{
@Override
public void run() {
for (int i = 0; i < 10 ; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
public void test(){
System.out.println("test....................");
}
}
注:根据Thread构造类,利用runable对象生成线程对象,且runbale多实现,具有可扩展性(里面能写很多类)
3、实现callable接口——callable在目前的图搜中已经使用,还得我旭哥
实现方式先总结下:
(1)生成callabele对象
(2)生成futuretask对象
(3)根据Thread构造器生成thread对象
public class ThreadDem_four {
public static void main(String[] args) {
MyCallable myCallable = new MyCallable();
FutureTask<String> task = new FutureTask<>(myCallable);
new Thread(task).start();
try {
//当去get的时候,CPU会让出时间片,让FutureTask种的任务先去进行执行
String s = task.get();
System.out.println(s);
} catch (Exception e) {
e.printStackTrace();
}
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + " : " + i );
}
}
}
//多实现,相当于可以业务分离
class MyCallable implements Callable<String>{
@Override
public String call() throws Exception {
int m = 0;
for (int i = 0; i < 100; i++) {
m += i;
}
return String.valueOf(m);
}
}
生成task,thread启动task,task.get()获取对应结果,在get时,cpu会让出足够的时间片。同时,它也可以抛出异常,这可以说是优势之一
注:Thread构造器总结
* —— thread类的构造器 * public Thread() * public Thread(String name)、 * public Thread(Runadle runable) * public Thread(Runable runable,String name)
可以看出来,在后两种构造器身上,实现了创建线程与业务实现解耦,这是后两种的优势
线程中常用的API
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread();
thread.getName();
thread.setName("qwq");
Thread.sleep(12121);
Thread.currentThread().getName();
thread.currentThread().setName("wqwqw");
}
先去记录这些,剩下的在接下来几期补充。