一,概念
多线程,是拿来干什么的,我们先从计算机整体开始说起来,计算机的组成cpu+内存+硬盘,就是我们只要的硬件设备,在我看来,计算机除了cpu内部最核心的地方是拿来进行计算出来的,其他都是用来进行存放数据的,当然在组合各系统工作中,还需要很多的转换器,也就是接口,计算机之间要进行通信,那么需要进行联网,这个网络信息发送也是一个大功能,这里虽然是java的一个基础,但是先不讨论。
计算机是拿来进行计算,其他功能都是辅助计算的,我们所谓的计算可能和你理解的1+1简单的计算不一样,这里可以理解为处理业务,一个应用代表一个进程,这里应该反过来说,我们的cpu进行处理,cpu是硬件,硬件的基础上还需要软件,操作系统来进行处理,所以扯到多线程,需要的东西还挺多的。
进程和线程,线程是进程的小孩子,一个进程拥有很多小孩子,也就是线程,线程可以共享进程的数据,为什么要产生线程?因为我们的cpu很快,而我们的内存,其他硬件很慢,为了提高cpu的使用率,推出了线程,举一个例子:cpu在处理一个a,现在b,c,d都在排队,等待a使用完毕cpu,再使用(这里其实就联系到了操作系统的原理了),如果a需要算一个1+3,那么cpu很快就工作完成了,但是a如果需要磁盘的一个小视频。。。那么磁盘很慢啊,机械盘还需要慢慢的把手臂移动过去,而cpu什么级别的,它就需要等待很久磁盘完成任务,这个时候,cpu就是空闲的,那么就是浪费资源,我们把进程切开,把一个任务一个任务分成很小的部分进行专业的执行,需要等待的时候,直接让出cpu,让cpu忙碌起来,你这个线程需要等待的时候,就让另外一个线程进行工作,这样就大大的提高了cpu的处理效率。而在用户开起来,这些线程是一起工作的,其实是轮流的,只是用户感受不到,这叫并发,而cpu现在的发展,有4核,8核,还有一个核对应两个线程的,也就是可以同时使用多个线程的,这叫做并行。
所以一般情况下,一个应用软件就对应一个进程,而一个进程下面有多个线程,这个时候,线程之间就需要通信,统一合作完成进程交给他们的任务,这个时候问题就来了,线程a,b,c都需要对一个数字w进行操作,比如说存钱和取钱,线程和线程之间,在cpu指中轮流切换的时候,是发现不了对方的,所以大家可能都给w存钱,但是w还没有反应过来,两个操作重叠了。这就是线程安全问题。
在操作系统中,线程分为用户线程和内核线程,用户线程是在内存中划分出来,又软件自行管理的,而内核线程是由操作系统调度的,一般应用使用的都是用户线程,但是jvm最开始是使用内核线程的模型在内存中开发出来用户线程的,但是后来jvm把线程的管理 直接交给了操作系统了,所以也算是内核线程了。
java HotSpot JVM后台运行系统线程主要分类:
二,Thread类
![](https://i-blog.csdnimg.cn/blog_migrate/06a40cb9cfb1d739725e6266e989c1f7.png)
![](https://i-blog.csdnimg.cn/blog_migrate/a90ab65fe74d84e2fd39335f3ff97095.png)
public class MyThread extends Thread{
public void run() {
System.out.println("run= "+this.isAlive());
}
public static void main(String []args) {
MyThread h=new MyThread();
System.out.println("begin= "+h.isAlive());
h.start();
System.out.println("end= "+h.isAlive());
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/94c81c0ae7dfea83c59c9368d187ac40.png)
public class MyThread extends Thread{
public void run() {
try {
System.out.println("begin= "+System.currentTimeMillis());
Thread.sleep(5000);
System.out.println("end= "+System.currentTimeMillis());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String []args) {
MyThread h=new MyThread();
h.start();
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/5deb014836d13bc9e1bd94ad1499eed5.png)
public class MyThread extends Thread{
public void run() {
long beantime=System.currentTimeMillis();
int count=0;
for(int i=0;i<=500000;i++) {
//Thread.yield();
count=count+(i+1);
}
long endtime=System.currentTimeMillis();
System.out.println("花费时间:"+(endtime-beantime));
}
public static void main(String []args) {
MyThread h=new MyThread();
h.start();
}
}
public class MyThread extends Thread{
public void run() {
try {
System.out.println(Thread.currentThread().getName()+" begin");
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName()+" end");
return ;
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName()+" 被中断了");
}
System.out.println("我异常退出了。。");
}
public static void main(String []args) throws InterruptedException {
MyThread h=new MyThread();
h.start();
Thread.sleep(1000);
h.interrupt();
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/7f631283d9ebc8df465dac9cce7aa7bb.png)
Thread thread=new Thread(new Runnable() {
public void run() {
//如果当前线程被中断则退出循环
while (!Thread.currentThread().isInterrupted())
System.out.println(Thread.currentThread()+"Hello");
}
});
public class MyThread extends Thread{
public void run() {
try {
System.out.println(System.currentTimeMillis()+" begin");
Thread.sleep(3000);
System.out.println(System.currentTimeMillis()+" end");
} catch (InterruptedException e) {
}
}
public static void main(String []args) throws InterruptedException {
MyThread h=new MyThread();
h.start();
// h.join();
System.out.println(System.currentTimeMillis()+" main end");
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/c445282d06a6962db87c3afef1d4a87a.png)
![](https://i-blog.csdnimg.cn/blog_migrate/dc261a434c95ff684b4396d68331ff2c.png)
suspend()与resume()
public class MyThread extends Thread{
private long i=0;
public long getI() {
return i;
}
public void run() {
while(true) {
i++;
}
}
public static void main(String []args) throws InterruptedException {
MyThread h=new MyThread();
h.start();
Thread.sleep(2000);//让子线程先跑一段。
h.suspend();// 暂停子线程,看一下i的值是多少
System.out.println("暂停: "+System.currentTimeMillis()+" i= "+h.getI());
Thread.sleep(2000); //再让子线程跑,看它跑得动吗?
System.out.println("暂停: "+System.currentTimeMillis()+" i= "+h.getI());
//唤醒
h.resume();
System.out.println("唤醒: "+System.currentTimeMillis()+" i= "+h.getI());
Thread.sleep(2000); //再让子线程跑,看它跑得动吗?
System.out.println("唤醒: "+System.currentTimeMillis()+" i= "+h.getI());
h.stop();
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/768da57e89229035ae9630e882b7b16f.png)