一、什么叫线程
说线程之前先要说一下进程,windows系统就是一个很大的进程,或者说由很多很多进程组合起来的,有的运行着wifi模块,有的在调度cpu等等,而线程是什么,线程就是一条一条的命令,或者是一个执行者,一个进程可以调度很多的线程去干活,搬砖
还有一个概念,线程呢,是程序执行的最小的单元,没有比这个更小的了,相当于古时候的小兵
可能说的不是很对,但是这是我理解的,权威解释:《百度百科》
二、Java 中的线程
相同,Java中也得需要线程去干活,就比如说实例化一个类,就是由一个或者多个线程共同调度所实现的结果。
Java 中有单线程、多线程这两种,一般呢,我们都是多线程去处理。
其实我们计算机就是多线程,不可能就一个线程在工作,那样的话你电脑得累死。
三、线程中的状态
Java中给我们提供了线程的创建、使用、销毁等等这些方法,看图说话
解释一下这个图,从new开始看起,线程首先得去创建,然后去cpu获取资源,然后去工作,工作途中可能遇到其他的线程在忙乎,于是线程可能还得等其他线程忙完了(因为cpu资源被占用光了),在去获取资源的时候还会碰到死锁、卡死等等问题,这个就涉及到程序调度的问题了,我们先不说这个问题。如果工作完成之后,就销毁这个线程,也就是dead。
四、单线程&多线程
单线程,就好比一个人在盖房子,自己又得搬砖、又得扛水泥
多线程,就好比一堆人在盖房子,有人搬砖,有人扛水泥
不用想都知道,多线程的效率高,盖房子的速度绝对要比一个人盖得要快
但是!多线程也有烦恼,一是难管理,二是消耗大
尽管这样,没办法,有的时候必须要这样去做,不然活太多干不完啊
五、使用
我们主要的东西在这里,我们先说一下如何创建线程
方法1:继承Thread类
然后我们来重写一下run方法,这个run方法,就是线程所要执行的方法。
快捷键:alt + shift + s 选择 这个
勾选run 然后确定
然后我们在run方法中输出一句话:
package com.java.test;
public class test extends Thread {
@Override
public void run() {
// TODO Auto-generated method stub
// super.run();
System.out.println("我是一个线程");
}
}
然后呢,我们弄个主函数,我们来调用一下这个run
public static void main(String[] args) {
test test = new test();
test.start();
}
这个start的方法就是线程的执行方法,我们实例化对象,然后让这个对象弄个线程,然后让他运行
是吧,这就是单线程
方法2:实现Runnable()接口
还是这个类,我们以后多用这个实现接口的这个方法去创建线程
原因:因为Java中只允许单继承,但是接口实现可以同时实现多个接口
调用啥的和上面的一样,大家可以进行调用,不过调用的是run
当然,除去这俩方式之外,还有其他的方法调用线程,这里我不多说,说多了记不住,而且也不怎么常用,想知道的可以自行百度
六、多线程
多线程就是创建多个单线程来完成某一件事情
但是这里要说一点,线程不会说一个一个执行的,它们是抢夺CPU资源的,谁先抢到了,谁就先来执行,不会说礼让啊啥的。
这里呢,我们来写一个demo来说明一下这个多线程的使用
吃饺子
我们设定10 个包子,然后,张三去吃包子去。我们来看代码如何去写:
package com.java.test;
public class test implements Runnable {
private int jiaozi = 1;
private String threadName;
public test(String threadName) {
// TODO Auto-generated constructor stub
this.threadName = threadName;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(jiaozi <= 10) {
System.out.println(threadName + "在吃第" + jiaozi + "个饺子");
jiaozi++;
}
}
public static void main(String[] args) {
test test1 = new test("张三");
test1.run();
}
}
我们定义一个全局变量饺子 = 1,然后弄一个构造方法,谁谁谁在吃饺子
然后执行
我们会发现,张三线程正在吃饺子
这样就是一个单线程了,我们再来多弄一个线程
赵四线程
package com.java.test;
public class test implements Runnable {
private int jiaozi = 1;
private String threadName;
public test(String threadName) {
// TODO Auto-generated constructor stub
this.threadName = threadName;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(jiaozi <= 10) {
System.out.println(threadName + "在吃第" + jiaozi + "个饺子");
jiaozi++;
}
}
public static void main(String[] args) throws InterruptedException {
test test1 = new test("张三");
test test2 = new test("赵四");
Thread thread1 = new Thread(test1);
Thread thread2 = new Thread(test2);
thread1.start();
thread2.start();
}
}
我们可以看结果
我们不难看出,每运行一次,就有一次结果,而且结果都不一样
这就说明线程并没有按照我们想要的样子去执行,而是真正的抢资源,谁拿到谁来用
但是,有一个问题,他俩都能够吃到10个饺子,很明显,一个饺子只能一个人吃,不可能给俩人都吃到的,所以,我们来修改一下
package com.java.test;
public class test implements Runnable {
public volatile int jiaozi = 1;
@Override
public void run() {
// TODO Auto-generated method stub
while(jiaozi <= 10) {
this.eat();
}
}
public synchronized void eat() {
if(jiaozi > 10) {
return;
}
System.out.println(Thread.currentThread().getName() + "在吃第" + jiaozi + "个饺子");
jiaozi++;
}
public static void main(String[] args) throws InterruptedException {
test test1 = new test();
Thread thread1 = new Thread(test1, "张三");
Thread thread2 = new Thread(test1, "赵四");
thread1.start();
thread2.start();
}
}
线程这里的使用,其实不止这些,更重要的是后面的多线程开发,这个是个难点,而且特别不容易理解,而且以后企业呢用的也多,我们之后会推出项目,大家可以多学习学习。
大家有什么不懂得地方可以加我QQ:2100363119