一、Process与Thread
1.1 定义:
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的一个独立单位。
线程是进程的一个实体,是CPU调度和分派的基本单位,他是比进程更小的能独立运行的基本单位,线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),一个线程可以创建和撤销另一个线程;
1.2 区别![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/d7c38dc9d2714bc5cf2e8b2e319d052b.png)
备注:没有线程的进程这个说法不对,凡是进程必须有并且至少有一个线程。
二、 多线程的创建
2.1 创建线程的方式
主要有以下两种:
- 继承Thread类
使用步骤:
1、继承Thread类 + 重写run方法;
2、创建是先烈 + 调用start方法开启多线程
代码实现:
public class StartThread extends Thread{
@Override
public void run() {//重写run方法
for (int i = 0; i < 20; i++) {
System.out.println("一边听歌");
}
}
public static void main(String[] args) {
StartThread st = new StartThread();
st.start();//调用start方法开启进程,不保证立即执行 cpu调用
//st.run();//普通方法调用
for (int i = 0; i < 20; i++) {
System.out.println("一边coding");
}
}
- 实现Runnable接口
使用步骤:
1、创建:实现Runnable + 重写run
2、启动:创建实现类对象 + Thread对象 + start
代码实现:
public class StartThread2 implements Runnable{
//线程入口点
@Override
public void run() {
for (int i = 0; i < 50; i++) {
System.out.println("一边听歌");
}
}
public static void main(String[] args) {
//创建实现类对象
StartThread2 st2 = new StartThread2();
//创建代理类对象
Thread t = new Thread(st2);
t.start();
//new Thread(new StartThread2()).start();
for (int i = 0; i < 50; i++) {
System.out.println("一边coding");
}
}
实现多线程的高级方法(暂时先了解):
- 实现Callable接口,实现call()方法
注意:要多用实现Runnable,少用继承
2.2 多线程会出现的问题
代码模拟多线程抢票:
public class Web12306 implements Runnable {
private int ticketNum = 99;
@Override
public void run() {
while (true){
if (ticketNum < 0){
break;
}
try {
Thread.sleep(200);//模拟网络延迟
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "-->"+ ticketNum--);
}
}
public static void main(String[] args) {
//一份资源
Web12306 web = new Web12306();
//多个代理
new Thread(web,"张三").start();
new Thread(web,"李四").start();
new Thread(web,"王五").start();
}
会造成如下问题:并发问题,因此要保证线程安全(数据准确)
扩展:
多线程常见的十大问题