当前位置: 首页 > news >正文

上海做网站哪家便宜网站建设客户资料收集清单

上海做网站哪家便宜,网站建设客户资料收集清单,怎么给我 的网站做关键词,wordpress土豆插件java如何创建线程1. java如何创建线程1.1 通过继承Thread类来创建线程1.2 通过实现Runnable接口来创建线程1.3 通过匿名内部类来创建线程1.4 lambda表达式1.5 通过实现Runnable接口的方式创建线程目标类的优缺点1. java如何创建线程 一个线程在Java中使用一个Thread实例来描述…

java如何创建线程

  • 1. java如何创建线程
    • 1.1 通过继承Thread类来创建线程
    • 1.2 通过实现Runnable接口来创建线程
    • 1.3 通过匿名内部类来创建线程
    • 1.4 lambda表达式
    • 1.5 通过实现Runnable接口的方式创建线程目标类的优缺点

1. java如何创建线程

一个线程在Java中使用一个Thread实例来描述。Thread类是Java语言的一个重要的基础类,位于java.lang包中。Thread类有不少非常重要的属性方法用于存储和操作线程的描述信息.

Thread类的构造方法:

在这里插入图片描述

1.1 通过继承Thread类来创建线程

666
666
666
666
(1) 继承Thread类,创建一个新的线程类。

(2) 同时重写run()方法,将需要并发执行的业务代码编写在run()方法中。

代码写法如下:

class MyThread extends Thread {
//注释这个方法重写了父类方法@Overridepublic void run() {//需要并发执行的代码System.out.println("hello t");}
}
public class ThreadDemo1 {//第一种写法是使用Thread的run描述线程入口public static void main(String[] args) {Thread t = new MyThread();//向上转型t.start();//会创建新的线程System.out.println("hello main");}
}

此时我们可以运行一下:

在这里插入图片描述
此时呢~
我们就通过start()创建了一个新的线程,并且由于我们调用了start(),所以系统自动帮我们调用了run(),此时的run()是执行在 t 线程里面的.

我们可以通过打开jconsole.exe 这个文件来查看我们java在执行期间运行的线程.

由于线程执行完就会结束,为了方便查看,我们写一个死循环来方便我们观看.

在这里插入图片描述

在这里插入图片描述
此时,红色框框里面的main线程就是我们的主线程,另一个Thread-0就是我们刚才创建的一个 t 线程,由于我们没有指定名字,所以这个线程名字默认从0往后递增~

在这里插入图片描述
红色框框里面的两个构造方法是可以修改这个线程的名字的,先讲第一个红色框框里面的.

我们先在MyThread这个类中,通过快速创建构造方法,将可以传入名字参数的构造方法写出来.
在这里插入图片描述

class MyThread extends Thread {//调用父类的构造方法public MyThread(String name) {super(name);}@Overridepublic void run() {while (true){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("hello t");}}
}

此时呢?我们就可以对这个线程起名字了.

在这里插入图片描述

1.2 通过实现Runnable接口来创建线程

写一个类MyRunnable实现Runnable接口,覆写run()方法,创建MyRunnable对象runnable,将runnable作为参数调用Thread有参构造,创建线程thread,调用start()启动线程。

我们先查看一下Runnable这个接口.


Runnable有且仅有一个抽象方法 —— void run(),代表被执行的用户业务逻辑的抽象,在使用的时候,将用户业务逻辑编写在Runnable实现类的run()方法中。当Runnable实例传入Thread实例的target属性后,Runnable接口的run()的方法将被异步调用。

如何理解上面这句话呢?

我们先理解第一句话: 将用户业务逻辑编写在Runnable实现类的run()方法中.

在这里插入图片描述

由于我们的MyThread这个类实现了Runnable这个接口,所以我们需要重写这个接口里面的run()方法.如上图.

我们再来理解第二句话: 当Runnable实例传入Thread实例的target属性后,Runnable接口的run()的方法将被异步调用。

首先呢?我们需要new一个Runnable的实例.

 MyRunnable myRunnable = new MyRunnable();

接着又讲到将Runnable的实例传入到Thread实例的target属性.

target是什么?

在Thread类的run()方法中,如果target(执行目标)不为空,就执行target属性的run()方法。而target属性是Thread类的一个实例属性,并且target属性的类型为Runnable

在这里插入图片描述

此时我们的MyRunable的类型就是target的类型(Runnable),所以此时我们实例的 myrunable 就可以作为参数传入到Thread的构造方法中.


class MyRunnable implements Runnable {@Overridepublic void run() {while (true){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("hello t");}}
}
public class ThreadDemo2 {//第二种方法是使用Runnable interface(接口) 来描述线程入口public static void main(String[] args) {//先实例化一个实现Runnable接口的类MyRunnable myRunnable = new MyRunnable();//将这个类的引用作为参数传入Thread的构造方法中Thread t = new Thread(myRunnable);//此时可以通过start()创建一个线程,在这个线程中调用这个MyRunnable这个类中的run()方法.t.start();while (true) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("hello main");}}
}

当我们运行时:

在这里插入图片描述

当然,我们也可以自己指定线程名字,这里就不进行演示了.

1.3 通过匿名内部类来创建线程

因为有些线程是只需要调用一次的,所以我们可以通过匿名内部类这样的方式来进行run()的重写.

代码如下:

在这里插入图片描述

在实例化这个对象时,在其后面写入一个{},此时就可以在这个{}中写入自己需要的方法.

注意:此时这个类是一次性的类.

上述代码的运行结果是:

在这里插入图片描述
可能有人就会问了,你这次怎么没有main线程啊,其实是因为main线程在执行完t.start()之后后续就没有代码需要执行了,所以自然这个线程就结束了,于是就是我们上述看到的,只有 t 线程.

在实现Runnable编写target执行目标类时,如果target实现类是一次性类,可以使用匿名实例的形式。

public class ThreadDemo4 {public static void main(String[] args) {Thread t = new Thread(new Runnable() {@Overridepublic void run() {while (true) {System.out.println("hello t");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}});t.start();while (true) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("hello main");}}
}

1.4 lambda表达式

使用Lambda表达式优雅地创建Runnable线程目标类
在这里插入图片描述
我们通过观察这个Runnable接口可以发现,上面有一串注释,@FunctionalInterface 这个注释的意思就是标记这个接口为函数式接口,在Java中,“函数式接口”是有且仅有一个抽象方法的接口。反过来说,如果一个接口中包含两个或两个以上的抽象方法,就不能使用@FunctionalInterface注解,否则编译会报错。

Runnable接口是一个函数式接口,在接口实现时可以使用Lambda表达式提供匿名实现,编写出比较优雅的代码。 如果一个接口中有多个抽象方法,那样没有办法使用Lambda表达式简化。

  public static void main(String[] args) {//()里面放参数,{}里面放函数体Thread t = new Thread(()->{while (true) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("hello t");}},"猪猪侠");t.start();while (true) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("hello main");}}

但是呢? 此时小鱼有一个问题问大家,大家对比五段代码,找到哪几个有错误并且说明错误原因.


public class ThreadDemo5 {
//例一static int count = 0;public static void main(String[] args) {Thread t = new Thread(()->{while (true){System.out.println(count);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});t.start();}
}
public class ThreadDemo5 {//例二public static void main(String[] args) {int count = 0 ;Thread t = new Thread(()->{while (true){System.out.println(count);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});count = 5;t.start();}
}
public class ThreadDemo5 {//例三public static void main(String[] args) {int count = 0 ;Thread t = new Thread(()->{while (true){System.out.println(count);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});t.start();}
}
public class ThreadDemo5 {//例四public static void main(String[] args) {final int count = 0 ;Thread t = new Thread(()->{while (true){System.out.println(count);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});t.start();}
}
public class ThreadDemo5 {//例五public static void main(String[] args) {int count = 0 ;Thread t = new Thread(()->{while (true){System.out.println(count++);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});t.start();}
}

(1) 第一个没有错误,由于count是成员变量,在线程中是共享资源,所以lambda表达式中是可以访问这个变量并且对其进行修改的.
(2) 第二个有错误,Lambda 表达式(匿名类) 不能访问非 final 的局部变量 .

因为成员变量存在堆中,而局部变量是在栈上分配,存在于虚拟机栈的局部变量表中,Lambda 表达(匿名类) 有可能会在另一个线程中执行。如果在线程中要直接访问一个局部变量,可能线程执行时该局部变量已经被销毁了,而 final 类型的局部变量在 Lambda 表达式(匿名类) 中其实是局部变量的一个拷贝

(3) 第三个没有错误,虽然我们的count是局部变量,但是由于我们的代码并未有对该变量进行后续的修改,我们可以称这个count变量为实际final,意思就是虽然没有被final修饰,但是由于并没有修改这个变量的值,所以在lambda表达式中可以使用.
(4) 没有问题

(5) 错误,lambda表达式不能修改局部变量.原因如下:

lambda表达式不能修改局部变量

1.5 通过实现Runnable接口的方式创建线程目标类的优缺点

通过实现Runnable接口的方式创建线程目标类有以下缺点:

  • 所创建的类并不是线程类,而是线程的target执行目标类,需要将其实例作为参数传入线程类的构造器,才能创建真正的线程。
  • 如果访问当前线程的属性,不能直接访问Thread的实例方法,必须通过Thread.currentThread()获取当前线程实例,才能访问和控制当前线程。

通过实现Runnable接口的方式创建线程目标类有以下优点:

  • 可以避免由于Java单继承带来的局限性。如果异步逻辑所在类已经继承了一个基类,就没有办法再继承Thread类。比如,当一个Cat类继承了Animal类,再要继承Thread类就不行了。所以在已经存在继承关系的情况下,只能使用实现Runnable接口的方式。
  • 逻辑和数据更好分离。通过实现Runnable接口的方法创建多线程更加适合同一个资源被多段业务逻辑并行处理的场景。在同一个资源被多个线程逻辑异步、并行处理的场景中,通过实现Runnable接口的方式设计多个target执行目标类可以更加方便、清晰地将执行逻辑和数据存储分离,更好地体现了面向对象的设计思想。
http://www.yayakq.cn/news/376559/

相关文章:

  • 惠州淡水网站建设公司wordpress编辑页面
  • 手工制作网站网站程序 wap pc 同步
  • 北京网站设计确保代码符合w3c解析域名就可以做网站
  • 有什么手机做网站的网站管理助手v3
  • 自己如何建企业网站不花钱网站怎么做
  • 招聘网站开发的公司成都网站建设制作价格
  • 山东金泰建设有限公司网站手机网站seo免费软件
  • 北京网站建设找华网天下建论坛网站需要多少空间
  • 白沟17网站一起做网店网站搭建好后被移动宽带屏蔽怎么办
  • 昆山哪家做网站好做网站怎么存放视频
  • wordpress网站底部导航代码wordpress ?p=29
  • 自己怎么做响应式网站0453牡丹江信息网
  • 大型门户网站系统北京seo代理计费
  • 正能量网站入口不用下载免费erp系统教程
  • 佛山网站建设哪家便宜东莞外贸公司网站建设
  • 公司做网站的费用怎么做账下列关于网站开发
  • 自己给网站做支付接口推荐西安优秀的高端网站建设公司
  • 凯叔讲故事网站谁做的低价备案域名购买
  • 网站设计psd网站建设投标书模板
  • 五合一小程序网站潍坊网站建设怎样
  • 在线制作动画的网站旅游网站做seo
  • 网站更改备案广西住建领域培训考试系统
  • 提高网站流量原则平台网站建设外包费用
  • 安徽合肥做网站的公司网络推广方案书模板
  • 网站源码是啥专业做网站建设设计
  • 备案做电影网站吗网站建设基础 ppt
  • 门户网站有哪些局限性一个商务宣传怎么做网站合适
  • 山东省城乡建设厅网站怎么网站建设公司
  • 深圳网站建设东营岳阳网格员
  • 如何建设网站网站wordpress前端地址