Java——多线程实现的三种方式

创建新执行线程有三种方法。

第一种方法是将类声明为 Thread 的子类。该子类应重写 Thread 类的 run 方法。接下来可以分配并启动该子类的实例。

例如,计算大于某一规定值的质数的线程可以写成:

class PrimeThread extends Thread {long minPrime;PrimeThread(long minPrime) {this.minPrime = minPrime;}public void run() {// compute primes larger than minPrime. . .}}

然后,下列代码会创建并启动一个线程:

     PrimeThread p = new PrimeThread(143);p.start();
1,继承Thread
定义类继承Thread
重写run方法
把新线程要做的事写到run方法中
创建线程对象
开启新线程,内部会自动执行run方法

具体的多线程实现代码如下:

package com.yy.thread;public class Demo2_Thread {
/*** 创建新执行线程有两种方法。* 一种方法是* ①将类声明为 Thread 的子类。* ②该子类应重写 Thread 类的 run 方法。* ③接下来可以分配并启动该子类的实例。* */public static void main(String[] args) {//开启一条线程Mythread mt = new Mythread();           //4,创建线程(Thread类)的子类对象mt.start();                             //5,开启线程,需要一定的时间,所以说,JVM会先执行for循环语句,也就是,会先输出bb,之后再输出aaaaaaa;然后再相互交替输出//public void start() : 使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
//      mt.run();                               //如果这样调用,只是调用了run方法,执行run方法里面的for循环,线程还是主线程这一个线程,不会出现交替的多线程形式//主线程for (int i = 0; i < 100; i++) {         //为了便于观察多线程的执行,在主方法里面进行for循环System.out.println("bb");           //这个for循环就是主线程的,两条线程开启多线程便于观察}//两条线程相互交替进行,即多线程实现}}
class Mythread extends Thread{                  //1,继承Threadpublic void run(){                          //2,重写run方法for (int i = 0; i < 100; i++) {         //3,将要执行的代码写到run方法中System.out.println("aaaaaaa");  }}
}

创建线程的第二种方法是声明实现 Runnable 接口的类。该类然后实现 run 方法。

然后可以分配该类的实例,在创建 Thread 时作为一个参数来传递并启动。

采用这种风格的同一个例子如下所示:

     class PrimeRun implements Runnable {long minPrime;PrimeRun(long minPrime) {this.minPrime = minPrime;}public void run() {// compute primes larger than minPrime. . .}}

然后,下列代码会创建并启动一个线程:
每个线程都有一个标识名,多个线程可以同名。如果线程创建时没有指定标识名,就会为其生成一个新名称。

     PrimeRun p = new PrimeRun(143);new Thread(p).start();
2,实现Runnable
定义类实现Runnable接口
实现run方法
把新线程要做的事先到run方法中
创建自定义的Runnable子类对象
创建Tread对象,传入Runnable
调用start()开启新线程,内部会自动调用Runnable的run()方法

具体的多线程实现代码如下:

package com.yy.thread;public class Demo3_Thread {
/*** 创建线程的另一种方法是* ①声明实现 Runnable 接口的类。* ②该类然后实现 run 方法。* ③然后可以分配该类的实例,在创建 Thread 时作为一个参数来传递并启动。* * Runnable里面只有一个run()方法,实现Runnable只需要重写run()方法即可* * * 实现Runnable的原理* 查看源码:*      1,看Thread类的构造函数,传递了Runnable接口的引用*      2,通过init()方法找到传递的target给成员变量的target赋值*      3,查看run方法,发现run方法中有判断,如果target不为null就会调用Runnable接口子类对象的run方法* */public static void main(String[] args) {MyRunnable wsq = new MyRunnable();                  //4,创建Runnable的子类对象
//      Runnable target = wsq;                              //父类引用指向子类对象,new MyRunnable()这个是子类对象也就是wsq  Thread yy = new Thread(wsq);                        //5,将其当作参数传递给Thread的构造函数; wsq代表Runnable的子类对象yy.start();                                         //6,开启线程; Thread里面才有start()方法//      new Thread(wsq).start();                            //这种方法与上面的两行代码实现的做用一样for (int i = 0; i < 100; i++) {System.out.println("你,陪我步入蝉夏,越过城市喧嚣,歌声还在游走,你榴花般的笑容");}}
}
class MyRunnable implements Runnable {                      //1,定义一个类,实现Runnable方法@Override   public void run() {                                     //2,重写run方法for (int i = 0; i < 100; i++) {                     //3,将要执行的代码写到run方法中System.out.println("我真的好想你,在每一个雨季。");           }}   
}

两种方法的区别:

  • a.继承Thread : 由于子类重写了Thread类的run(),当调用start()时,直接找子类的run()方法
  • b.实现Runnable : 构造函数中传入了Runnable的引用,成员变量记住了它,start()调用run()方法时内部判断成员变量Runnable的引用是否为空,不为空,编译时看的是Runnable的run(),运行时执行的时子类的run()方法

继承Thread(开发中优先考虑)

  • 好处:可以直接使用Thread类中的方法,代码简单

  • 弊端:如果已经有了父类,就不能有这个方法,因为java是单继承的

实现Runnable接口(实际上是对继承Thread的补充)

  • 好处:即使自己定义的线程类有了父类也没关系,因为有了父类也可以实现接口,接口是可以多实现的,拓展性强

  • 弊端:不能直接使用Thread中的方法,需要先获取到线程对象后,才能得到Thread的方法,代码复杂

第三种方法是创建类是实现Callable这个接口。然后该类重写 Callable这个接口里的抽象方法call。

Callable 接口类似于 Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。但是 Runnable 不会返回结果,并且无法抛出经过检查的异常。

案例:通过实现Callable这个接口,来实现多线程,创建一个求和类;

具体的多线程实现代码如下:


package com.yy.thread;import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;public class Demo6_Callable {
/*** 第三种线程创建方式* <T> Future<T> submit(Callable<T> task)* 提交一个返回值的任务用于执行,返回一个表示任务的未决结果的 Future。* 该 Future 的 get 方法在成功完成时将会返回该任务的结果。 * Callable 接口类似于 Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。但是 Runnable 不会返回结果,并且无法抛出经过检查的异常。* * */public static void main(String[] args) throws InterruptedException, ExecutionException {ExecutorService pool  = Executors.newFixedThreadPool(2);    //创建线程池,线程池里面可以养两个线程Future<Integer> f1 = pool.submit(new MyCallable(100));      //由于下面创建的类中里面有一个有参构造方法,这里得传一个参数Future<Integer> f2 = pool.submit(new MyCallable(50));//submit返回一个Future,所以说,应该用Future去接收//Future可以获取出来1-100或者是1-50的求和结果System.out.println(f1.get());System.out.println(f2.get());//V get()   throws InterruptedException,ExecutionException如有必要,等待计算完成,然后获取其结果。 pool.shutdown();                                            //关闭线程池}}
class MyCallable implements Callable<Integer>{                      //创建一个MyCallable类去实现Callable这个接口private int num;                                                //设置一个成员变量numpublic MyCallable (int num){                                    //创建一个有参构造方法this.num = num;                                             //num是传进去的数}@Overridepublic Integer call() throws Exception {                        //重写Callable这个接口里面的抽象方法call;这里的返回值类跟泛型<Integer>是一致的int sum = 0;                                                //实现求和代码for (int i = 1; i <= num; i++) {sum += i;}return sum;                                                 //返回sum}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/379966.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python网络编程---TCP客户端

0x01 环境 python2、 pycharm 0x02 程序 # -*- coding:UTF-8 -*- import sockettarget_hostwww.baidu.com tarfet_port80target_hostlocalhost target_port3345 dataABCDEF# 创建一个socket对象 client socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 连接客户端 clien…

c#枚举数字转枚举_C#枚举能力问题和解答 套装4

c#枚举数字转枚举1) What is the correct output of given code snippets in C#.NET? using System;class program{enum emp_salary : int{emp1 10000,emp2 15000,emp4 20000}static void Main(string[] args){int sal (int)emp_salary.emp2;Console.WriteLine(sal);}}100…

Java——匿名内部类实现线程的两种方式

package com.yy.thread;public class Demo4_Thread {public static void main(String[] args) {demo1(); //匿名内部类&#xff0c;第一种&#xff0c;继承Threaddemo2(); //匿名内部类&#xff0c;第二种&#xff0c;实现Runnable接口 }private static void…

zlib1.2.5的编译

zlib1.2.5没有了1.2.4的vc6工程&#xff0c;只好使用命令行编译。通过win32/Makefile.msc发现有4种编译方式&#xff0c;如下&#xff1a;# Usage:# nmake -f win32/Makefile.msc (standard build)# nmake -f win32/Makefile.msc LOC-DFOO …

python网络编程--UDP客户端

0x01 环境 python、pycharm 0x02 程序 # -*- coding:utf-8 -*-import sockettarget_host127.0.0.1 target_part80#创建一个socket对象 client socket.socket(socket.AF_INET,socket.SOCK_DGRAM)#发送一些数据 client.sendto(AAAAAA,(target_host,target_part))#接收到的消息 …

window.open参数和技巧

【1、最基本的弹出窗口代码】 <SCRIPT LANGUAGE"javascript"> <!-- window.open (page.html) --> </SCRIPT> 因为着是一段javascripts代码&#xff0c;所以它们应该放在<SCRIPT LANGUAGE"javascript">标签和</script>之间。…

java jar包示例_Java包getImplementationTitle()方法和示例

java jar包示例包类的getImplementationTitle()方法 (Package Class getImplementationTitle() method) getImplementationTitle() method is available in java.lang package. getImplementationTitle()方法在java.lang包中可用。 getImplementationTitle() method is used to…

Java——获取和设置多线程的名称

给名字进行赋值有两种方式&#xff1a; 1&#xff0c;通过构造去赋值 Thread(String name) 直接在构造方法里面传一个名字就行了2&#xff0c;通过set设置的方法进行赋值 package com.yy.threadmethod;public class Demo1_Name {public static void main(String[] args) {dem…

十三、oracle 数据字典和动态性能视图

一、概念数据字典是oracle数据库中最重要的组成部分&#xff0c;它提供了数据库的一些系统信息。动态性能视图记载了例程启动后的相关信息。 二、数据字典1)、数据字典记录了数据库的系统信息&#xff0c;它是只读表和视图的集合&#xff0c;数据字典的所有者为sys用户。2)、用…

python网络编程---TCP服务器

0x01 环境 python2 pycharm 0x02 程序 客户端程序&#xff1a; # -*- coding:UTF-8 -*- import sockettarget_hostwww.baidu.com target_port80target_hostlocalhost target_port3345 dataABCDEF# 创建一个socket对象 client socket.socket(socket.AF_INET,socket.SOCK_STRE…

C# 获取磁盘容量

/// 获取指定驱动器的空间总大小(单位为B) /// </summary> /// <param name"str_HardDiskName">只需输入代表驱动器的字母即可 </param> /// <returns> </returns> public static long GetHardDi…

Java——获取当前线程的对象(currentThread())(两种方式)

package com.yy.threadmethod;public class Demo2_CurrentThread { /*** public static Thread currentThread()返回对当前正在执行的线程对象的引用。 * 返回&#xff1a;当前执行的线程。返回的是一个Thread* 该方法主要是为了协助 实现通过Runnable接口来对线程进行设置…

HDU2501_多米诺骨牌

题目大意&#xff1a; 有一个大小是 2 x n 的网格&#xff0c;现在需要用2种规格的骨牌铺满&#xff0c;骨牌规格分别是 2 x 1 和 2 x 2&#xff0c;请计算一共有多少种铺设的方法。 解题思路&#xff1a; 找出递推公式&#xff1a; f[i] f[i-1] f[i-2] * 2; 代码&#xff1a…

java jar包示例_Java包getSpecificationVendor()方法和示例

java jar包示例包类的getSpecificationVendor()方法 (Package Class getSpecificationVendor() method) getSpecificationVendor() method is available in java.lang package. getSpecificationVendor()方法在java.lang包中可用。 getSpecificationVendor() method is used to…

sys.argv和getopt

0x01 sys.argv sys.argv用来读取命令行参数&#xff0c;保存程序的文件名和命令参数&#xff0c;读入的参数以列表保存 import sysprint sys.argv print type(sys.argv)可以看到&#xff0c;sys.argv把空格当成分隔符&#xff0c;空格两边的值当做sys.argv的一个元素&#xf…

[导入]《大话设计模式》重印公告

摘要: 《大话设计模式》12月中旬上市&#xff0c;至2008年1月底仅仅一个多月&#xff0c;5000册即销售一空&#xff0c;清华大学出版社已经开始重印&#xff0c;也就是说很快可以在二月底或三月初看到新印刷修正过大部分错误的《大话设计模式》。 阅读全文[新闻]《人民日报市场…

Java——线程的四种不同形式

一&#xff0c;休眠线程 public static void sleep(long millis) throws InterruptedException 在指定的毫秒数内让当前正在执行的线程休眠&#xff08;暂停执行&#xff09;&#xff0c;此操作受到系统计时器和调度程序精度和准确性的影响。该线程不丢失任何监视器的所属权。…

hdu1053 Entropy hdu2527 Safe Or Unsafe

裸裸的哈弗曼编码&#xff0c;求出哈弗曼编码的路径长度&#xff0c;注意整个字符串为一种字符的情况 View Code #include<iostream>#include<queue>#include<algorithm>#include<vector>using namespace std;struct node{int u,w; node(int a0,in…

Java ListResourceBundle getContents()方法与示例

ListResourceBundle类的getContents()方法 (ListResourceBundle Class getContents() method) getContents() method is available in java.util package. getContents()方法在java.util包中可用。 getContents() method is used to get the contents into the form of an Obje…

DOM元素的所有子元素 .elements

.elements属性用来获取某个DOM元素的所有子元素&#xff0c;是个很有用的属性&#xff0c;可用于用className来获取指定元素等用途。 转载于:https://www.cnblogs.com/cly84920/archive/2008/08/06/4427136.html