首先请注意:线程不是进程,不要将二者混淆。
1.什么是进程?
我们要知道,计算机上任何程序的运行都必须依托于内存。电脑中会有很多单独运行的程序,每一个可以独立运行的程序,都是一个进程。
任务管理器中每一项,都是一个进程。比如下图中的TIM、谷歌、有道云笔记等等。
任何一个进程都会独自占据内存一块空间,即进程之间是相互独立存在的
2.什么是线程?
进程想要执行任务就必须依赖线程。也就是说进程中的最小执行单位就是线程,并且每一个进程中至少有一个线程。
下面我们要了解一下串行和并行的概念:
(单线程)串行:比如我们下载多个文件时,在串行中它是按照一定的顺序去进行下载的,也就是说,必须等下载完A之后才能开始下载B,它们在时间上是不可能发生重叠的。
(多线程)并行:比如下载多个文件时,开启多条线程,多个文件同时进行下载,这里是严格意义上的,在同一时刻发生的,并行在时间上是重叠的。
线程池:管理线程,分配任务
实现方法是把数据放进队列里面,先进先出。实现自动分配多线程
3.线程的创建:
两种方式创建进程:
- 继承thread类:多个线程共同使用一个变量,即执行同一个任务时。
- 直接定义一个线程thread:不操作共享变量,即各自执行各自的任务时。
//定义一个线程thread
Thread t1=new Thread() {
public void run() {
//执行线程就是执行run方法
}
};
4.简单多线程代码举例
package com.test.threadnew;
public class Test01 {
public static void main(String[]args){
Thread t1=new Thread() {
public void run() {
getCount();
}
};
Thread t2=new Thread() {
public void run() {
getCount();
}
};
Thread t3=new Thread() {
public void run() {
getCount();
}
};
t1.start();//start并不是执行的意思。只是准备就绪
t2.start();
t3.start();
try {
t1.join();
t2.join();
t3.join();//加了join,就可以先执程这个三个线程,而不是下面的哈哈哈哈哈哈哈哈哈哈哈哈哈哈
} catch (Exception e) {
// TODO: handle exception
}
System.out.println("哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈");//如果不加join的话,由于system是I/O操作,所以最先执行
}
public static int count = 0;
public synchronized static void getCount() {
//加锁:synchronized,即给count的读写操作都加上了锁。
for(int i=0;i<10;i++) {
count ++;
System.out.println(count);
}
System.out.println("################################################");
return ;
}
}
多线程的本质是CPU的快速切换。一般每个小线程执行到一半就会被切换,不会等到执行结束才切换,所以会有时候得到的结果并不是我们所预期的,会发生覆盖。
上述代码由于在getCount()方法中加了“锁”,从而避免了线程在快速切换的过程中导致的错误。
我们也可以将synchronized关键字去掉,来观察一下最后的输出结果。此时的结果只是一种情况,每次的输出结果都是不相同的。
关于锁的具体内容,未完待续。。。