为什么要引入多线程编程
java引用进程的概念主要为了解决 “并发编程” 的问题,即多个程序一起运行;
锁紧弄成编程已经可以解决并发编程的问题,并且可以利用CPU多核资源了

因此,线程也就应运而生,线程也叫 “轻量级进程”;
解决并发编程问题,最终是为了让创建,销毁,调度的速度更快;
为什么线程更轻?
因为线程把创建资源,释放资源的过程都给省下了
如何理解线程
看例子:
上篇博客我们把纺织厂的例子来比喻进程,这篇博客继续使用这个例子:

为什么说线程把创建资源,释放资源的过程都给省下了呢?
因为 线程A和线程B共享进程里面的资源,就相当于本来是1个人吃10只鸡,多加了一个线程之后就相当于多加了一个人,现在就相当于2个人吃10只鸡;一个进程里面的所有线程都是资源都是共享的,因此创建线程不需要创建和释放资源
画图解释一下多进程和多线程的关系

第一种方式是多进程,会浪费调大量资源,花费大量成本,去重新申请一个进程
第二种是多线程方式,直接在一个进程里完成即可,省下很多成本,并且提高了速度
重点:是不是一味的在一个进程里面申请线程,速度就可以一直提升呢?
答案肯定是不行的,增加线程数量的时候,也不是一直可以提高速度的,因为纺织厂的空间是有限的,生产线过多,机会拥挤,反而会影响速度;同理,线程太多,核心数目有限,大量的时间反而浪费在线程调度上了
java中操作多线程,最核心的类是Thread,记住就行了;不要纠结为啥是这个类
创建线程的目的是为了成立一个独立的执行流(执行一段代码)
看代码:
class MyThread extends Thread{
//重写子类的 run()方法,告诉线程要做什么工作
@Override
public void run() {
while(true){
System.out.println("==MyThread==");
//休眠1s,让线程运行速度变慢,方便观看效果
try {
sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public class Test1 {
public static void main(String[] args) throws InterruptedException {
Thread thread = new MyThread();
thread.start();//真正创建了一个线程
//理解为死循环打印==main==即可
while(true){
System.out.println("==main==");
thread.sleep(1000);//休眠1s,让线程运行速度变慢,方便观看效果
}
}
}

问题:为什么不在main()中调用run方法?
如果在main()调用run,此时就没有创建新线程,全程都只有main线程在运行


以上就是多线程编程的一个典型例子,即main线程和thread线程同时执行,谁先谁后我们也不确定;
java中创建线程的写法有很多种,上面写的是第一种即继承Thread,重写run方法
class MyRunnable implements Runnable{
@Override
public void run() {
while(true){
System.out.println("==MyRunnable==");
try {
sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public class Test1 {
public static void main(String[] args) throws InterruptedException {
Runnable runnable = new MyRunnable();//创建一个任务
Thread thread = new Thread(runnable);//把任务交给线程来处理
thread.start();//真正创建了一个线程,去执行任务
//理解为死循环打印==main==即可
while(true){
System.out.println("==main==");
sleep(1000);//休眠1s,让线程运行速度变慢,方便观看效果
}
}
}
结果:打印如果依旧是 顺序不确定的

为什么要这样写? 目的是为了让线程和线程之间要做的工作分开.解耦合;
这一种方法是最推荐的,也是最方便的
public static void main(String[] args) {
//直接把Lambda任务传给Thread构造方法
Thread thread = new Thread(() ->{
System.out.println("==Lambda==");
});
thread.start();
System.out.println("==main==");
}

//构造方法举例
Thread t1 = new Thread();
Thread t2 = new Thread(new MyRunnable());
Thread t3 = new Thread("名字");
Thread t4 = new Thread(new MyRunnable(), "名字");

public static void main(String[] args) {
Thread thread1 = new Thread("第一个线程的名字");
System.out.println(thread1.getName());//获取线程的名字
System.out.println(thread1.getId());//获取线程的id
}
结果:

2.获取线程状态
getState()方法;
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(() -> {
System.out.println("==thread1==");
});
thread1.setDaemon(true);
thread1.start();//线程运行
System.out.println(thread1.getState());//在线程正在运行是获取线程状态,就是runnable
thread1.join();//等到线程结束
System.out.println(thread1.getState());//线程结束之后,再获取线程状态就是结束的状态了,TERMINATED
}
运行结果:



public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(() -> {
System.out.println("==thread1==");
});
System.out.println(thread1.isAlive());//false,并没有创建线程,只是创建了对象,所以是false
thread1.start();
System.out.println(thread1.isAlive());//true,创建了线程,并且并没有执行完,所以是true
thread1.join();
System.out.println(thread1.isAlive());//false,线程已经执行完任务并且线程已经销毁,所以线程状态是false
}



线程调度是一个随机的过程,等待线程就是了控制两个线程结束的顺序

在这里我们讨论的都是线程,并不是进程
