当前位置: 首页 > 后端技术 > Java

多线程原理和常用方法以及Thread和Runnable的区别

时间:2023-04-01 14:21:16 Java

多线程原理随机打印CPU有两条执行路径,CPU有一个选择,一个执行main方法,一个执行run方法.也可以说是两个线程,一个主线程,一个运行线程,一起请求CPU的执行权(执行时间)。谁抢到它就会执行相应的代码。多线程内存图。main方法的第一步是创建一个对象,创建一个堆内存存储。在堆内存中(地址值赋值给变量名0x11),run方法在mt时被压入栈中。其他方法)mt.start()调用时会开辟一个新的栈空间。执行run方法(run方法不是在主线程中执行,而是在一个新的栈空间中执行,如果再次启动,会再开辟一个栈空间,多一个线程)。对于cpu来说,cpu有权利选择执行main方法,也可以执行两个run方法。多线程的优点:多线程执行时,在栈内存中,每个执行线程实际上都有一块属于自己的栈内存空间,多个线程执行方法push和pop栈时互不影响。Thread类获取线程名的常用方法getName()publicstaticvoidmain(String[]args){//创建Thread类的子类对象MyThreadmt=newMyThread();//调用start方法开启新线程,执行run方法mt.start();新的MyThread().start();新的MyThread().start();//链式编程System.out.println(Thread.currentThread().getName());}/**获取线程的名称:1.使用Thread类中的方法getName()StringgetName()返回线程的名称。2、可以先获取当前正在执行的线程,使用线程中的getName()方法获取线程的名称。staticThreadcurrentThread()返回对当前正在执行的线程对象的引用。*@authorzjq*///定义Thread类的子类publicclassMyThreadextendsThread{//重写Thread类中的run方法设置线程任务@Overridepublicvoidrun(){//获取线程名称//字符串名称=getName();//System.out.println(名称);//链式编程System.out.println(Thread.currentThread().getName());}}输出如下:mainThread-2Thread-0Thread-1设置线程名setName()ornewThread("threadname")使用Thread类中的方法setName(name)voidsetName(Stringname)更改线程名称使其与参数名称相同。创建一个带参数的构造方法,其中传递线程的名称;以父类的参数调用构造方法,将线程名传递给父类,让父类(Thread)给子线程起一个名字Thread(Stringname)来分配一个新的Thread对象。复制代码代码案例://启用多线程MyThreadmt=newMyThread();mt.setName("小强");mt.start();//启用多线程newMyThread("旺财").start();让当前执行的线程暂停指定的毫秒数sleep(longmillis)代码示例:publicstaticvoidmain(String[]args){//模拟秒表for(inti=1;i<=60;i++){System.out.println(i);//使用Thread类的sleep方法让程序休眠1秒try{Thread.sleep(1000);}catch(InterruptedExceptione){e.printStackTrace();}}}创建多线程程序的第二种方式——实现Runnable接口实现Runnable接口实现多线程步骤:创建一个Runnable接口的实现类,在实现类中重写Runnable接口的run方法,并设置线程任务创建一个Runnable接口的实现类对象创建一个Thread类对象。在构造方法中,通过Runnable接口的实现类对象调用Thread类中的start方法,开启一个新线程执行run方法。代码示例如下:/***1.创建Runnable接口的实现类*@authorzjq*/publicclassRunnableImplimplementsRunnable{//2.在实现类中重写Runnable接口的run方法,设置线程任务@Overridepublicvoidrun(){for(inti=0;i<20;i++){System.out.println(Thread.currentThread().getName()+"-->"+i);}}}publicstaticvoidmain(String[]args){//3.创建Runnable接口的实现类对象RunnableImplrun=newRunnableImpl();//4.创建一个Thread类对象,构造方法中传入Runnable接口的实现类对象Threadt=newThread(run);//打印线程名//5.调用Thread类中的start方法启动一个新的线程并执行运行方法t.start();for(inti=0;i<20;i++){System.out.println(Thread.currentThread().getName()+"-->"+i);}}Thread和Runnable的区别实现Runnable用接口创建多线程程序的好处:1.避免单继承的局限,一个类只能继承一个类(一个人只能有一个父类),以及继承Thread类的类不能再继承其他类。实现Runnable接口,也可以继承其他类,实现其他接口。2.增强程序的可扩展性,降低程序的耦合(解耦)。Runnable接口的实现方式将设置线程任务与开启新线程分离(解耦)。在实现类中,重写了run方法:用于设置线程任务。创建一个Thread类对象并调用start方法:用于启动一个新的线程。使用匿名内部类来启动线程。匿名内部类似于启动线程以简化代码编码。代码示例如下:/**匿名内部类方法实现线程创建Anonymous:无名内部类:写在其他类内部的类匿名内部类功能:简化代码,从父类继承子类,重写方法父类的,一步创建子类对象。实现实现类实现类接口,重写接口中的方法,创建实现类对象一步合成匿名内部类的最终产物:子类/实现类对象,该类无名称格式:new父类/接口(){重复父类/接口中的方法};*@authorzjq*/publicclassDemo01InnerClassThread{publicstaticvoidmain(String[]args){//线程的父类是Thread//newMyThread().start();newThread(){//重写run方法,设置线程任务@Overridepublicvoidrun(){for(inti=0;i<20;i++){System.out.println(Thread.currentThread().getName()+"-->"+"詹");}}}。开始();//线程接口Runnable//Runnabler=newRunnableImpl();//多态Runnabler=newRunnable(){//重写run方法并设置线程任务@Overridepublicvoidrun(){for(inti=0;i<20;i++){System.out.println(Thread.currentThread().getName()+"-->"+"线程");}}};新线程(r).start();//简化接口的方式newThread(newRunnable(){//重写run方法,设置线程任务@Overridepublicvoidrun(){for(inti=0;i<20;i++){System.out.println(Thread.currentThread().getName()+"-->"+"zjq");}}}).start();}}