zoukankan      html  css  js  c++  java
  • 多线程(1)

    多线程运行原理

    简单来说,多线程就是在程序执行的时候,再创建一个新的线程类,主程序执行的时候,是开辟了一条通往cpu的路径,而在主程序里面,有调用线程类的代码,也就是在执行的过程中,又开辟了一条新的通往cpu的路线。这也就是说,cpu在执行的时候就有了选择的余地,可以执行主线程,也可以执行线程类的内容,因为我们 无法控制cpu执行哪个,这也就是多线程的随机执行的原因。

    Thread类

    构造方法:

    1. public Thread() :分配一个新的线程对象。
    2. public Thread(String name) :分配一个指定名字的新的线程对象。
    3. public Thread(Runnable target) :分配一个带有指定目标新的线程对象。
    4. public Thread(Runnable target,String name):分配一个带有指定目标新的现成对象并指定名字。

    常用方法:

    1. public String getName():获取当前线程名称。
    2. public void start():导致此线程开始执行;java虚拟机调用此线程的run方法。
    3. public void run():此线程要执行的任务在此处定义代码。
    4. public static void sleep(long millis):使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行)
    5. public static Thread currentThread():返回对当前正在执行的线程对象的引用。

    Thread和Runnable的区别
    如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。
    总结
    实现Runnable接口比继承Thread类所具有的优势:

    1. 适合多个相同的程序代码的线程去共享同一个资源。
    2. 可以避免java中的单继承的局限性。
    3. 增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独立。
    4. 线程池只能放入实现Runnable或Callable类线程线程,不能直接放入继承Thread的类。

    在java中,每次程序运行至少启动两个线程,一个是main线程,一个是垃圾收集线程。因为每当使用了java命令执行一个类的时候,实际上都会启动一个JVM,每一个JVM其实就是在操作系统中启动了一个进程。

    获取线程的名称

    1. 使用Thread类中的getName():String getName() 返回该线程的名称。
    2. 可以先获取到当前正在执行的线程,使用线程中的方法getName()获取线程名称:static Thread currentThread() 返回对当前正在执行线程对象的引用。

    代码演示:
    获取线程名称方法1

    package day27;
    import java.sql.SQLOutput;
    public class xiancheng01 extends Thread{    
        @Override   
        public void run(){        
            String name = getName();        
            System.out.println(name);    
        }
    }
    

    获取线程名称方法2

    package day27;
    public class xiancheng03 extends Thread{    
        @Override    
        public void run(){        
            Thread t = Thread.currentThread();        
            System.out.println(t);    
        }
    }
    

    Thread类的常用方法sleep

    public static void sleep(long millis):使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行)毫秒数结束之后,线程继续执行。

    因为sleep方法本身是带有异常的,所以要使用try...catch方法解决。

    代码演示:

    package day27;
    public class SleepDemo01 {    
        public static void main(String[] args) {        
            //模拟秒表        
            for (int i = 0; i < 60; i++) {            
                System.out.println(i);            
                //使用Thread类的sleep方法让程序睡眠1秒            
                try {                
                    Thread.sleep(1000);            
                } catch (InterruptedException e) {                
                    e.printStackTrace();            
                }        
            }    
        }
    }
    

    实现Runnable接口

    创建多线程程序的第二种方式:实现Runnable接口
    java.lang.Runnable
    Runnable 接口应该由那些打算通过某一线程执行其实例的类来实现。类必须定义一个称为run的无参数方法。
    java.lang.Thread类的构造方法
    Thread(Runnable target) 分配新的Thread对象。
    Thread(Runnable target,String name) 分配新的Thread对象。

    实现步骤:

    1. 创建一个Runnable接口的实现类。
    2. 在实现类中重写Runnable接口的run方法,设置线程任务。
    3. 创建一个Runnable接口的实现类对象。
    4. 创建Thread类对象,构造方法中传递Runnable接口的实现类对象。
    5. 调用Thread类中的start方法,开启新的线程执行run方法。

    代码演示:

    package day27;
    //创建一个Runnable接口的实现类
    public class RunnableImpl implements Runnable{    
        @Override    
        public void run(){        
            for (int i = 0; i < 20; i++) {          
                System.out.println(Thread.currentThread().getName()+"-->"+i);        
            }    
        }
    }
    
    package day27;
    public class RunnableDemo02 {    
        public static void main(String[] args) {        
            //创建一个Runnable实现类对象         
            RunnableImpl run = new RunnableImpl();        
            //创建Thread类对象,构造方法中传递Runnable接口的实现类对象        
            Thread t = new Thread(run);        
            //调用start方法,开启新的线程执行run方法        
            t.start();        
            for (int i = 0; i < 20; i++) {            
                System.out.println(Thread.currentThread().getName()+"-->"+i);        
            }    
        }
    }
    

    实现Runnable接口创建多线程程序的好处:

    1. 避免了单继承的局限性
      一个类智能集成一个类,类继承了Tread类就不能继承其他类。
      实现了Runnable接口,还可以继承其他的类,实现其他的接口。
    2. 增强了程序的扩展性,降低了程序的耦合性(解耦)
      实现Runnable接口的方式,把设置线程任务和开启新线程进行了奋力(解耦)
      实现类中,重写了run方法:用来设置线程任务。
      创建Thread类对象,调用start方法:用来开启新线程。

    匿名内部类的方式实现线程的创建

    匿名:没有名字
    内部类:卸载其他类内部的类

    匿名内部类作用:简化代码
    把子类继承父类,重写父类的方法,创建子类对象合一步完成
    把实现类实现类接口,重写接口中的方法,创建实现类对象合成一步完成。

    匿名内部类的最终产物:子类/实现类对象,而这个类没有名字

    格式:
    new 父类/接口(){
    重复父类/接口中的方法
    };

    代码演示:

    package day27;
    public class Demo03 {    
        public static void main(String[] args) {        
            //线程的父类是Thread        
            // new Mythread().start();        
            new Thread(){            
                @Override            
                public void run(){                
                    for (int i = 0; i < 20; i++){                    
                        System.out.println(Thread.currentThread().getName()+"-->"+"小明");                
                    }            
                }        
            }.start();        
            //线程的接口Runnable        
            //Runnable r = new RunnableImpl(); //多态        
            Runnable r = new RunnableImpl(){            
                @Override            
                //重写run方法,设置线程任务            
                public void run(){                
                    for (int i = 0; i < 20; i++) {                    
                        System.out.println(Thread.currentThread().getName()+"-->"+"君君");                
                    }            
                }        
            };        
            new Thread(r).start();    
        }
    }
    

    并发与并行

    并发:指两个或多个事件在同一个时间段内发生。
    并行:指两个或多个事件在同一时刻发生(同时发生)。

    线程与进程

    进程:是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个进程从创建、运行到消亡的过程。
    线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。

    简而言之,一个程序运行后至少有一个进程,一个进程中可以包含多个线程。

    线程调度

    • 分时调度
      所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间。
    • 抢占式调度
      优先让优先级高的线程使用CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性),Java使用的为抢占式调度。

    主线程

    执行主方法(main方法)的线程就是主线程

    单线程程序:java程序中只有一个线程。
    执行从main方法开始,从上到下依次执行。

    主线程概念:
    JVM执行main方法,main方法会进入到栈内存
    JVM会着操作系统开辟一条main方法桐乡cpu的执行路径,cpu就可以通过这个路径来执行main方法,这个路径就叫做main线程,也叫主线程。

    文章未经本人允许,禁止转载。 有技术问题,可加好友讨论。 联系方式:QQ:MjgxMjMxODAzNQ== 微信:bzNycjByLVhpYW9taW5n
  • 相关阅读:
    c 的内存分配与释放原则: 通常应遵循“谁malloc,谁free”的原则。
    总算知道怎样从ImageMagick生成的数据转换成HICON: MagickGetImageBlob & LookupIconIdFromDirectoryEx
    收藏:Non-direct与direct ByteBuffer区别
    java NIO 直接与非直接缓冲区
    [收藏]:[算法]LRU和LFU的区别
    异步IO的并发能力:backlog的配置很重要
    ByteBuffer: 当由一个byte[]来生成一个固定不变的ByteBuffer时,使用ByteBuffer.wrap(byte[]);
    ByteBuffer的allocate与allocateDirect2013-01-11
    Windows完成端口与Linux epoll技术简介
    Java并发——Fork/Join框架与ForkJoinPool
  • 原文地址:https://www.cnblogs.com/Xiaoming0/p/13894299.html
Copyright © 2011-2022 走看看