进程、线程、CPU还有效率(Java)

进程与线程

1、进程是程序的一次动态执行过程,这个过程也是进程本身从产生到消亡的过程。

2、由于cpu有“分时机制”,所以每个程序都能循环获得cpu的时间片段。加之CPU的执行速度快,感觉上像是同时在运行。

3、多线程是实现并发机制的一种有效手段,线程是比进程更小的执行单位,是进程的基础上进一步的划分。

4、一个进程可能包含多个同时执行的线程。

5、main()函数开始运行的线程为主线程。

6、 在Java中有两类线程:User Thread(用户线程)、Daemon Thread(守护线程)。他们之间的区别在于JVM。

7、用户线程:所有用户线程结束,jvm关闭;

8、守护线程:只有守护线程了,jvm可以关闭(也就是说守护线程不依赖于终端,但是依赖于系统,与系统“同生共死”)。

9、守护线程是后台默默地完成一些系统性的服务,比如垃圾回收线程、JIT线程。用户线程可以理解为是系统的工作线程,它会完成这个程序需要完成的业务操作。

10、通过Thread.setDaemon(false)设置为用户线程,通过Thread.setDaemon(true)设置为守护线程。

线程的生命周期
 

1、线程创建之后,进入新建状态,jvm给他分配内存空间,并且进行初始化。当线程对象的start()方法被调用,线程就处于可执行状态。

2、处于可执行状态的线程,随时可被CPU调度执行。

3、CPU执行该线程的时候,线程进入执行状态。中间可能会进入阻塞状态或者就绪状态。

4、直至线程异常或者线程正常结束或者return了数据。线程结束,整个生命周期结束。

开启新线程

1、继承Thread类,重写run()方法

   class FrozenTread extends Thread {
        @Override
        public void run(){
           dosomething();
        }
    }

    //调用
    FrozenTread item = new FrozenTread();
    item.start(); 

2、实现Runnable接口,重写run()

 //1):定义一个类A实现于java.lang.Runnable接口,注意A类不是线程类.
    class FrozenImplements implements Runnable{
        //2):在A类中覆盖Runnable接口中的run方法.
        @Override
        public void run() {
            //3):在run方法中编写需要执行的操作
           dosomething();
        }
    }
 //调用
   FrozenImplements item = new FrozenImplements();
   Thread thread = new Thread(item);
   thread.start();
  

3、直接在函数体使用

   //单CPU创建10个线程
   ExecutorService pool = Executors.newFixedThreadPool(10);
   pool.execute(new Runnable() {
        @Override
        public void run() {
          dosomething();
        }
   }
   pool.shutdown();
   while(true){
      if(pool.isTerminated()){
         break;
       }
   }
  

或者

  Thread t = new Thread(new Runnable(){
        @Override
        public void run(){
            // run方法具体重写
           dosomething();
        }});
  t.start();

循环插入mysql一万条数据,测试效率

新鲜供测试的数据库

1、常规写法,不开启新线程

 public String aaa(){
        long start = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            try {
                String sql = "insert into ceshi(uuid,test,name,age) values(1234,'22222','2020年7月1日15:46:14',123)";
                jdbcTemplate.execute(sql);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        long end = System.currentTimeMillis();
        String abc= end - start+"毫秒";
        System.out.println(abc);
        return abc;
    }

2、使用ExecutorService,开启10个线程

【拓展】

ExecutorService共有四种线程池:CachedThreadPool可缓存线程池、SingleThreadExecutor单线程池、FixedThreadPool固定线程数线程池、ScheduledThreadPool 固定线程数,支持定时和周期性任务线程池。

 public String bbb(){
        long start = System.currentTimeMillis();
        ExecutorService pool = Executors.newFixedThreadPool(10);
            pool.execute(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 10000; i++) {
                        try {
                            String sql = "insert into ceshi(uuid,test,name,age) values(1234,'22222','哈哈哈多喝点',123)";
                            jdbcTemplate.execute(sql);
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }
                 }
            });
        pool.shutdown();
        String abc;
        while(true){
            if(pool.isTerminated()){//终结者
                long end = System.currentTimeMillis();
                abc= end - start+"毫秒";
                System.out.println(abc);
                break;
            }
        }
        return abc;
    }

数据成功插入

3、实现java.lang.Runnable接口,开启两个线程

//1):定义一个类A实现于java.lang.Runnable接口,注意A类不是线程类.
    class FrozenImplements implements Runnable{
        //2):在A类中覆盖Runnable接口中的run方法.
        @Override
        public void run() {
            //3):在run方法中编写需要执行的操作
            for (int i = 0; i < 5000; i++) {
                try {
                    String sql = "insert into ceshi(uuid,test,name,age) values(1234,'22222','哈哈哈多喝点',123)";
                    jdbcTemplate.execute(sql);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    }
    public String ddd(){
        long start = System.currentTimeMillis();
        try {
            FrozenImplements item = new FrozenImplements();
            Thread thread = new Thread(item);
            Thread thread1 = new Thread(item);
            thread.start();
            thread1.start();
            //一个线程在启动后就马上执行,必须调用 Thread.Join()方法
            thread.join();
            thread1.join();
        }catch (Exception e){
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        return end- start +"毫秒";
    }

数据成功插入

效率分析

1、从上面的实现我们可以看出,开启多个线程,表面上执行效率是有所提高。

2、我们的计算机,一般只有一个CPU。多线程只不过是CPU在不同时间片之间的切换和调度。快慢未可知

3、是不是说开启多个线程,效率就高了或者因为CPU的切换和调度变慢了。这个问题无法给你准确的答案,CPU是和其他硬件设备一起工作的。多线程的目的可以最大限度的提高硬件设备的利用率。

4、也就是说,一个单CPU。多线程是否有效率在于,CPU的效率和其他配合硬件的效率。这是一个不断优化,依照实际情况而定的过程(开启几个线程,是否需要开启线程)。

5、多个cpu的时候,计算机适当多开启几个线程同时处理,会提高效率

6、服务器端最佳线程数量=((线程等待时间+线程cpu时间)/线程cpu时间) * cpu数量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
>