进程和线程的理解

1.进程是操作系统中资源分配的最小单位;线程是cpu调度的最小单位

--操作系统不直接给线程分配资源,线程使用的是进程的资源

--cpu调度时,调度的是进程内的线程

--线程被包含在进程中,是进程中的实际运作单位

--一条线程是进程中一条单一顺序的控制流,一个进程中可以并行多条线程执行不同的任务

2.进程有独立的地址空间;同一个进程内的线程共享当前进程的数据和地址空间;

--地址空间 是一种抽象的概念;每个进程都有自己独立的地址空间;他是进程与外部世界隔离的一种机制,别的进程不能访问或篡改当前进程内的数据和代码

3.高并发编程时可以选择多进程和多线程;多进程并发时,内存相互独立,通信的时候需要使用管道、消息队列、共享内存等 ;多线程共享进程的内存,线程间的通信更方便;进程的销毁需要释放内存空间

4.一个进程内可以创建多少个线程呢?32位操作系统用户态的虚拟内存空间假设有3G ,一个线程最少需要10M 那理论上可以创建300个线程;64位操作系统用户态的虚拟内存有128TB,可以创建无限个线程;需要操作系统的其他限制控制

5.进程上下文切换 涉及 地址空间、寄存器、打开的文件描述符 等信息的保存和恢复;

线程上下文切换,因为线程共享了地址空间和大部分资源;所以只需要保存和恢复部分寄存器信息

性能开销更小

6.如果要模拟CPU打满,需要使用多进程,创建和cpu个数相等个数的多进程,每个进程执行死循环永不停止

def cpu_bound():
    while True:
        pass

if __name__ == '__main__':
    # 创建多进程 有几个cpu 就创建几个进程 进程执行函数可以实现将cpu打满
    num_cores = multiprocessing.cpu_count()
    processes = []
    for i in range(num_cores):
        p = multiprocessing.Process(target=cpu_bound)
        p.start()
        processes.append(p)

    print("主进程等待子进程结束")
    for p in processes:
        p.join()
    print("主进程结束")

JVM进程、线程和操作系统中的进程、线程的关系

1.JVM从程序入口main方法启动后,就有了一个JVM进程,main方法是主线程;jvm中没有多进程编程,只有多线程编程;多线程使用synchronization等进行并发控制

2.java1.2之前 线程使用的是绿色线程,由jvm虚拟机调度,和操作系统无关;但由于和原生线程相比限制较多;在java1.2之后开始使用native thread,本质上就是操作系统中的线程

3.java线程有6种状态

BLOCKED 多个线程在等待synchronized同步资源时 等待

WAITING  线程的执行流程中调用了如Object.wait()等方法而进入等待状态

TIMED_WAITING  线程的执行流程中调用了如Thread.sleep(1)等方法而进入限时等待状态

操作系统线程有3种状态

java中多线程编程,共享资源同步控制的解决法案

synchronized作用在方法或代码块中;同一时刻只有一个线程访问共享资源,其他线程将被阻塞,直到当前线程执行完毕并释放锁synchronized 锁住的对象必须是全局共享的对象;否则锁住的不是一个对象,同步控制不生效
AtomicInteger原子变量  处理整数类型的数据 可以处理单个整型变量操作的场景 如计数器 序列号生成等如果涉及到复杂的复合运算或者需要保证多个变量的一致性  就需要结合synchronized 确保数据的完整性和一致性
volatile一个变量被volatile修饰时,每次修改该变量都直接从主存修改,而不是线程私有的本地内存,确保所有线程看到的内容是一样的  可以处理单个变量的可见性
ReentrantLock比synchronized更灵活互斥  可重入 可设置为公平锁

package com.company.thread;
public class Printtask implements Runnable {
    //    锁对象也必须是全局的静态变量 否则不是一个锁对象 也不能控制并发
    private static Object lock = new Object();
//    共享变量必须是类级别的变量 因为他们可以在所有实例对象之间共享,并且只有一份副本存在于内存中
    private static int count = 1;
    private String name;
    Printtask(String name) {
        this.name = name;
    }
    @Override
    public void run() {
        synchronized (lock) {
            System.out.println(name + "正在打印:");
                try {
                    // 让线程休眠一段时间,模拟打印过程
                    count++;
                    Thread.sleep(10);
                    count--;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            System.out.println(count);
        }
    }

    public static void main(String[] args) throws InterruptedException {

        Thread t1 = new Thread(new Printtask("aaaa"));
        Thread t2 = new Thread(new Printtask("bbbb"));
        Thread t3 = new Thread(new Printtask("cccc"));

        t1.start();
        t2.start();
        t3.start();

        t1.join();
        t2.join();
        t3.join();

    }
}

参考文档:

Java线程和操作系统线程的关系——从源码尝试解答 - 知乎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值