Java多线程

基础概念

  1. 进程:操作系统进行资源分配的最小单元,资源包含(CPU,内存,磁盘IO等)。比如:打开一个Office就是开启了一个进程
  2. 线程:CPU调度的最小单元,线程不能脱离进程存在。同一个进程中的多个线程共享进程的全部资源,每个线程仅仅只有很少部分私有资源(程序计数器,虚拟机栈,本地方法栈)。比如:打开多个word文档
  3. 多核心:一个芯片(CPU)上集成多个处理器核心,按照正常情况一个核心运行一个线程
  4. 多线程:让同一个处理器上的多个线程同步执行并共享处理器的执行资源,目前核心数:线程数 = 1:2
  5. 时间片轮转调度(RR算法):一种最古老、最简单、最公平且使用最广的算法,又称RR调度。每个进程被分配一个时间段,称作它的时间片,即该进程允许运行的时间
  6. 结论可以归结如下:时间片设得太短会导致过多的进程切换,降低了CPU效率:而设得太长又可能引起对短的交互请求的响应变差。将时间片设为100ms通常是一个比较合理的折衷。进程进行上下文切换是一个很耗时的操作
  7. 并发量:单位时间内处理的量,不能脱离单位时间
    • 并发:指应用能够交替执行不同的任务,比如单CPU核心下执行多线程并非是同时执行多个任务,如果你开两个线程执行,就是在你几乎不可能察觉到的速度不断去切换这两个任务,已达到"同时执行效果",其实并不是的,只是计算机的速度太快,我们无法察觉到而已.
    • 并行:指应用能够同时执行不同的任务,例:吃饭的时候可以边吃饭边打电话,这两件事情可以同时执行
      两者区别:一个是交替执行,一个是同时执行.

Java的多线程

多线程的好处
  1. 充分利用CPU的资源,减少CPU的空闲时间。1.6G的一个电脑,CPU执行一个指令的时间约为0.6纳秒(1秒= 1 0 9 {10^9} 109纳秒)
  2. 加快响应用户的时间,一个任务分成多个线程去执行,然后合并。减少整体的执行时间
  3. 可以使你的代码模块化,异步化,简单化。将相同和不同的模块进行拆分,如:下订单,发邮件,发短信等
多线程程序的注意事项
  1. 因为多个线程共享一个进程里面的所有资源,那么就可能带来线程安全问题,多个线程同时对一个共享全局变量、静态变量进行修改时(哪怕是最简单的 count++),也会造成数据的不准确
  2. 为了解决线程安全问题,加入了Java的锁机制,在同一个时刻保证只有一个线程访问共享变量,这样就不会有数据不准确问题,但是同时又会带来死锁问题。不同的线程都在等待那些根本不可能被释放的锁,如:两个线程相互持有对方需要的锁,又相互等待对方释放锁。
  3. 线程太多了会将服务器资源耗尽形成死机当机,每个线程运行都需要系统资源,系统内存以及CPU的“过渡切换”。解决这个问题,尽量用线程池,如果数据库连接池,资源池(资源库)等

Java天生就是多线程,就比如一个简单的main函数,JVM就会开启几个线程

public class OnlyMain {
    public static void main(String[] args) {
        //Java 虚拟机线程系统的管理接口
        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
        // 不需要获取同步的monitor和synchronizer信息,仅仅获取线程和线程堆栈信息
        ThreadInfo[] threadInfos =
                threadMXBean.dumpAllThreads(true, true);

        // 遍历线程信息,仅打印线程ID和线程名称信息
        for (ThreadInfo threadInfo : threadInfos) {
            //1 纳秒 nanoseconds = 10的负9次方秒,计算CPU及各个硬件所运行的速度的运行单位。
            System.out.println("[" + threadInfo.getThreadId() + "] " + threadInfo.getThreadName()+" times:"+threadMXBean.getThreadCpuTime(threadInfo.getThreadId()));
//            StackTraceElement[] stackTrace = threadInfo.getStackTrace();
//            for(StackTraceElement element : stackTrace) {
//                System.out.println("class:"+element.getClassName()+"-method:"+element.getMethodName());
//            }

        }
    }
}
运行结果:
cn.enjoyedu.ch1.base.OnlyMain
[6] Monitor Ctrl-Break times:31250000  //监控Ctrl-Break中断信号的
[5] Attach Listener times:0 //内存dump,线程dump,类信息统计,获取系统属性等
[4] Signal Dispatcher times:0  // 分发处理发送给JVM信号的线程
[3] Finalizer times:0 // 调用对象finalize方法的线程
[2] Reference Handler times:0  //清除Reference的线程
[1] main times:250000000  //main线程,用户程序入口
线程启动
  1. X extends Thread //继承Thread类
  2. X implements Runnable //实现Runnable接口
    X.start() //启动线程的唯一入口 --仅仅是使线程进入准备阶段,等待CPU分配时间片后,执行
    X.run() //仅仅是线程处理事件的方法,不是启动线程的方法,就相当于一个普通方法

注 意 : s t a r t ( ) 方 法 不 能 重 复 调 用 , 见 下 面 源

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值