进程和线程
进程(process):切换开销大
每一个独立运行着的软件,就叫做进程
多进程:在操作系统中同事运行多个程序
进程的特点:
a.独立性:不同的进程之间是独立的,相互之间资源不共享
b.动态性:进程在系统中不是静止不动的,而是在系统中一直活动的
c.并发性:多个进程可以在单个处理器上同时进行,且互不影响
线程(Thread):切换开销小
程序内部的一条执行路径。是进程的组成部分,一个进程可以有多个线程,每个线程去处理一个特定的子任务
一个进程可以有多个线程,每个线程都有自己的任务,一个进程中至少包含一个线程
多线程:在同一应用程序中多条执行路径同时执行
线程的特点:
线程的执行是抢占式的,多个线程在同一个进程中可以并发执行
进程和线程的关系以及区别
a、一个进程可以包含多个线程,但是至少需要有一个线程,否则这个进程是没有意义的
b、进程间不能共享资源,但线程之间可以
c、系统创建进程需要为进程重新分配系统资源,而创建线程则容易的多,因此使用线程实现多任务并发比多进程的效率高
多线程的实现
main 线程 主线程 是唯一一个不需要程序员自己创建自己调用的线程,是由jvm创建的
自己创建的叫子线程
// 线程的名字
System.out.println(Thread.currentThread().getName());
多线程创建方式有三种:
1、继承Thread类
2、实现Runnable接口
3、实现Callable接口
1、继承Thread类
①、定义一个类继承Thread类
②、重写run方法
③、创建子线程对象
赋值名字
1 给子线程赋值名字setName(name);
2. 通过构造方法给子线程赋值名字
public MyThread2(String name) {
// 2. 通过构造方法给子线程赋值名字
super(name);
this.name = name;
}
public static void main(String[] args) {
// main 线程 主线程
// 自己创建的叫做 子线程
MyThread thread = new MyThread();
MyThread thread2 = new MyThread();
// 启动线程
thread.start();
thread2.start();
for (int i = 0; i < 20; i++) {
System.out.println("主线程: "+i);
}
}
// 创建线程的时候 需要 Thread线程类
class MyThread extends Thread{
// 自定义子线程是因为有任务, 没有任务则不需要创建线程
@Override
public void run() {
// 任务要写在run方法中
for (int i = 0; i <20; i++) {
System.out.println("子线程: "+i);
}
}
}
结果:
当多个线程互不相干,自己只需要做自己的事情的时候,就可以使用继承Thread的方式
例:
四个窗口买票,每个窗口想要卖20张票
public static void main(String[] args) {
Thread ck = new Ck("窗口一");
Thread ck2 = new Ck();
ck2.setName("窗口二");
Thread ck3 = new Ck();
ck3.setName("窗口三");
Thread ck4 = new Ck();
ck4.setName("窗口四");
ck.start();
ck2.start();
ck3.start();
ck4.start();
}
class Ck extends Thread{
int ticket = 20;
// 给线程起名字
public Ck(String name) {
super(name);
}
public Ck() {
}
@Override
public void run() {
// for (int i = 20; i > 0; i--) {
// System.out.println(Thread.currentThread().getName()+"卖出第"+i+"张票");
// }
for (int i = 0; i <= 20; i++) {
ticket--;
System.out.println(Thread.currentThread().getName()+"买了"+i+"张");
}
}
}
结果:
还剩多少张
@Override
public void run() {
for (int i = 1; i <= 20; i++) {
tickt--;
System.out.println(Thread.currentThread().getName()+"买了"+i+"张票"+"还剩"+(tickt)+"张");
}
}
实现Runnable接口方式
1、自定义一个实现类,实现Runnable
2、重写run方法
public static void main(String[] args) {
// 创建Runnable的实现类对象
Ticket ticket = new Ticket();
// 创建线程对象
Thread t = new Thread(ticket);
Thread t2 = new Thread(ticket);
Thread t3 = new Thread(ticket);
Thread t4 = new Thread(ticket);
// 四个线程共享了一个ticke他空间
t.start();
t2.start();
t3.start();
t4.start();
// 常用格式 匿名内部类
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("i"+i)