zoukankan      html  css  js  c++  java
  • java线程从没入门就放弃

                    进程:是一次程序的执行,是一个包含自身执行地址的程序。进程是系统进行资源分配和调度的一个独立单位。在多任务操作系统中,可以把cpu时间分配给每一个进程。一个程序进入内存运行,即变成一个进程。进程是处于运行过程中的程序,并且具有一定独立功能。简单的说就是正在运行的程序就是进程(最简单的例子就是你的任务管理器)。
                    进程拥有自己独立的资源和自己私有的地址空间。就是程序在多道程序系统中的一次执行过程,它是动态产生,动态消亡的,具有自己的生命周期和各种不同的状态。进程具有并发性,它可以同其他进程一起并发执行,按各自独立的、不可预知的速度向前推进。 
               并发指的是同一时刻只能有一条指令执行,但多个进程指令被快速轮换执行,看起来就好像多个指令同时执行一样。
                    现在的计算机和手机等基本上都是支持多进程操作,比如使用计算机时可以边上网,边听音乐,边打lol等等。然而计算机只有一块cpu,并不能同时运行这些程序,cpu实际上是利用不同时间段去交替执行每个进程。
                    简单来说,进程就是由程序数据进程控制块三部分组成。
            线程:现代操作系统调度的最小单元 也叫轻量级进程, 在一个进程里可以创建多个线程, 这些线程都拥有各自的计数器、 堆栈和局部变量等属性, 并且能够访问共享的内存变量。 处理器在这些线程上高速切换, 让使用者感觉到这些线程在同时执行线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。线程的堆空间是共享的,栈空间是独立的,线程消耗的资源比进程小的多
            单线程:一个程序内部某个结构化的控制流程,有的时候被称作"执行环境"或轻量级程序,它是一个由上而下的结构化程序。
            多线程:在单个程序中同时运行多个线程完成不同的工作。
            一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。

            并行:指两个或多个时间在同一时刻发生(同时发生);

       并发:指两个或多个事件在一个时间段内发生。

            目前电脑市场上说的多核 CPU,便是多核处理器,核 越多,并行处理的程序越多,能大大的提高电脑运行的效率。

            单核处理器的计算机肯定不能并行的处理多个任务,只能是多个任务交替的在单个 CPU 上运行。

            因为一个进程中的多个线程是并发运行的,那么从微观角度看也是有先后顺序的,哪个线程执行完全取决于 CPU 的调度,程序员是干涉不了的。而这也就造成的多线程的随机性。
            Java 程序的进程里面至少包含两个线程,主进程也就是 main()方法线程,另外一个是垃圾回收机制线程。每当使用 java 命令执行一个类时,实际上都会启动一个 JVM,每一个 JVM 实际上就是在操作系统中启动了一个线程,java 本身具备了垃圾的收集机制,所以在 Java 运行时至少会启动两个线程。
            由于创建一个线程的开销比创建一个进程的开销小的多,那么我们在开发多任务运行的时候,通常考虑创建多线程,而不是创建多进程。
            在Java Web中要注意,线程是JVM级别的,在不停止的情况下,跟JVM共同消亡,就是说如果一个Web服务启动了多个Web应用,某个Web应用启动了某个线程,如果关闭这个Web应用,线程并不会关闭,因为JVM还在运行,所以别忘了设置Web应用关闭时停止线程。
            多线程是为了同步完成多个任务,不是为了提高程序运行效率,而是通过提高资源使用效率来提高系统的效率。
            进程和线程的创建:在java中,线程是一种对象,但并非所有对象都可以成为线程,只有实现了Runnable接口或者继承了Thread类的对象才能成为线程。
            

    常用的windows 应用软件命令

        1、regedit打开注册表编辑器

        2、control打开控制面板

        3、msconfig打开系统配置

        4、gpedit.msc打开本地组策略

        5、explorer打开资源管理器

        6、taskmgr任务管理器

        7、logoff直接注销计算机

        8、osk打开屏幕键盘

        9、calc打开计算器

        10、mspaint:调出画图软件

        11、dxdiag查看电脑详细配置信息

        12、mstsc:打开远程桌面连接

        13、systeminfo查看计算机基本信息

        14、notepad:打开记事本

            
              进程的创建:通过 Runtime 类的 exec() 方法来创建进程
                  表示当前进程所在的虚拟机实例,每个Java应用程序都有一个Runtime类的Runtime ,允许应用程序与运行应用程序的环境进行接口。
                  由于任何进程只会运行与一个虚拟机实例当中,即只会产生一个虚拟机实例(底层源码采用 单例模式)
                  当前运行时可以从getRuntime方法获得
    package com.alphabet.Process;
    import java.io.IOException;
    public class Process {
        /**
         * 用java打开记事本
         * @throws IOException 
         */
        public static void main(String[] args) throws IOException {
            Runtime run=Runtime.getRuntime();
            //使用Runtiome的exec方法
            run.exec("mspaint");//打开画板
            run.exec("notepad");//打开画板
            //ProcessBuilder的start方法
            ProcessBuilder pb=new ProcessBuilder("notepad");
            pb.start();
        }
    }
    源码可以看到,构造器私有化了,即外部我们不能 new 一个新的 Runtime 实例,而内部给了我们一个获取 Runtime 实例的方法 getRuntime() 。
    通过 ProcessBuilder 创建进程
            
            线程创建传统有两种方式:
                      继承了Thread类,
                          实现了Runnable接口。
                   线程在API中有一个类Thread,Thread和它的子类才能被称为线程类
    package com.alphabet.Process;
    public class classA extends Thread{
        @Override
        public void run() {//线程执行值
            // TODO Auto-generated method stub
            for (int i = 0; i < 50; i++) {
                System.out.println("播放音乐第"+i+"首");
            }
        }
        public static void main(String[] args) {
            //创建线程方法(并启动线程)
            /**
             * 语法如下
             *     classA a=new classA();
             *     a.start;//启动一个线程
             * 不要调用run方法,如果调用run方法的话,好比调用普通方法。依然还是只有一个线程,并没有开启新的线程
             * java虚拟机在负责线程的调度问题,哪个线程执行完全取决于 CPU 的调度,
             * 程序员是干涉不了的。而这也就造成的多线程的随机性。
             */
            for (int i = 0; i < 50; i++) {
                System.err.println("打游戏"+i);
                if(i==10) {
                    //创建线程并启动线程
                    classA a=new classA();
                        a.start();
                }
            }
        }
    }
     
    package com.alphabet.Process;
    public class SimpleRunnable implements Runnable {
        //SimpleRunnable不是线程类
        @Override
        public void run() {
            // TODO Auto-generated method stub
            System.out.println("请开始你的表演");
        }
         public static void main(String[] args) {
             SimpleRunnable target=new SimpleRunnable();
            Thread t=new Thread(target);
            t.start();
        }
    }
    package com.alphabet.Process;
     
    public class classB {
        public static void main(String[] args) {
            for(int i = 0 ; i < 10 ; i++){
                System.out.println("玩游戏"+i);
                if(i==5){
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            for(int i = 0 ; i < 10 ;i++){
                                System.out.println("播放音乐"+i);
                            }
                        }
                    }).start();
                }
            }
        }
    }
        线程的生命周期:创建,可执行,运行,阻塞,死亡  不能多次启动同一个线程,即多次调用 start() 方法,只能调用一次,否则报错

    1、新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new Thread();

    2、就绪状态(Runnable):也被称为“可执行状态”。当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;

    3、运行状态(Running):当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;

    4、阻塞状态(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才有机会再次被CPU调用以进入到运行状态。根据阻塞产生的原因不同,阻塞状态又可以分为三种:

    (1)等待阻塞 -- 运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;

    (2)同步阻塞 -- 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;

    (3)其他阻塞 -- 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

    5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

            线程的优先级:优先级的范围在1-10,默认值为5;可以使用Thread类中setPriority()方法来设定,但必须在1-10以内,不然会报错。优先权教高的,会被提前执行,当他执行完成才会轮到优先权较低的线程执行。如果优先权相同,那么采用轮流执行的方式.但是,线程优先级不能保证线程执行的顺序。

            线程的控制:
                    线程的控制包括线程的启动、挂起、状态检查以及如何正确结束线程,由于在程序中使用多线程,为合理安排线程就绪状态。
                    线程的常用方法:
                                public void start()
                            使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
                         public void run()
                            如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回。
                         public final void setName(String name)
                             改变线程名称,使之与参数 name 相同。
                         public final void setPriority(int priority)
                                         更改线程的优先级。
                                    public final void setDaemon(boolean on)
                                         将该线程标记为守护线程或用户线程。
                                    public final void join(long millisec)
                                         等待该线程终止的时间最长为 millis 毫秒。
                                    public void interrupt()
                                        中断线程。
                                    public final boolean isAlive()
                                        测试线程是否处于活动状态。
                                    public static void yield()
                                        暂停当前正在执行的线程对象,并执行其他线程。
                                    public static void sleep(long millisec)
                                        在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。
                                    public static boolean holdsLock(Object x)
                                        当且仅当当前线程在指定的对象上保持监视器锁时,才返回 true。
                                    public static Thread currentThread()
                                        返回对当前正在执行的线程对象的引用。
                                    public static void dumpStack()
                                        将当前线程的堆栈跟踪打印至标准错误流。
                      结束线程:
                                    自然死亡:一个线程从run方法的结尾处结束,子安消亡不能再被运行。
                         强制死亡:调用thread类中stop方法强制停止
                后台线程:Daemon线程,后台执行服务的线程例如java的垃圾回收
                thread.setDaemon(boolean on);
                on:表示为true,将线程标记为后台线程。
                
                线程死锁:
                    多线程以及多进程改善了系统资源的利用率并提高了系统 的处理能力。然而,并发执行也带来了新的问题——死锁。所谓死锁是指多个线程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进程都将无法向前推进。
                所谓死锁是指两个或两个以上的线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。
               产生的必要条件: 

                    互斥条件:一个资源每次只能被一个进程使用。独木桥每次只能通过一个人。

                    请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。乙不退出桥面,甲也不退出桥面。

                    不剥夺条件: 进程已获得的资源,在未使用完之前,不能强行剥夺。甲不能强制乙退出桥面,乙也不能强制甲退出桥面。

                    循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。如果乙不退出桥面,甲不能通过,甲不退出桥面,乙不能通过。

  • 相关阅读:
    Delphi TCXTreeList的一些操作
    Authentication failure. Retrying 彻底解决vagrant up时警告
    Linux查看mysql 安装路径和运行路径
    和重复搭建开发环境说 Bye Bye 之Vagrant
    怎样查看MySql数据库物理文件存放位置
    10分钟彻底理解Redis持久化和主从复制
    胡子决定编程语言运势
    总结: asp.net页面间数据传递(转)
    利用System.IO中的Directory类对目录进行基本操作
    SQL中读出表中字段
  • 原文地址:https://www.cnblogs.com/lw687a/p/9662207.html
Copyright © 2011-2022 走看看