目录
3.1.1Thread.start()和Thread.run()方法的区别
在java标准库中,给我们提供了一个标准的Thread类,来操作线程。Thread 类也可以视为是 Java 标准库提供的 API(API:Thread 类提供的方法 和 类)。当我们创建好Thread对象,其实和操作系统中的线程是相对应的。即如果我们想要先创建一个线程,就要先创建一个Thread类的对象。
首先我们先创建子类,让其继承Thread,并且重写run方法
我们这里的创建线程都是在同一个进程内部实现的。另外我们为了更清楚的表示线程的并发执行,再来举其他的例子:
即创建一个类实现Runnable接口,再创建 Runnable实例,并传给Thread实例
通过 Runnable 来描述任务的内容
进一步的再把描述好的任务交给 Thread 实例
class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println("hello Thread");
}
}
public class TestDemo2 {
public static void main(String[] args) {
//这里我们实例化的是Thread本身
//构造方法里面指定了Runnable实例
Thread t = new Thread(new MyRunnable());
t.start();
}
}
public class TestDemo3 {
public static void main(String[] args) {
Thread t = new Thread(){
@Override
public void run() {
System.out.println("hello Thread");
}
};
t.start();
}
}
这里使用了匿名内部类,同时重写run方法和new了个匿名内部类的实例
public class TestDemo4 {
public static void main(String[] args) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("hello thread");
}
});
t.start();
}
}
针对 Runnable 接口 创建的 匿名内部类(这个匿名内部类实现了Runnable 接口)。
同时 将创建出的实例 作为 参数 传给了 Thread 的构造方法.
小结:上述四个方法,我们认为Runnable方法更好一点,因为它能够让线程与线程之间的任务更能够解耦,即让代码之间高内聚,低耦合。即同一类功能的代码放一起,不同功能模块之间,没有关系。也就是说,Runnable只是单纯的描述了一个任务的具体内容,但要怎么执行,它并不关心。
public class TestDemo5 {
public static void main(String[] args) {
//这是方法4的简化,其中()表示无参数的run方法
Thread t = new Thread(()->{
System.out.println("hello Thread");
});
t.start();
}
}
public class TestDemo6 {
private static final long count = 10_0000_0000;
public static void serial() {
//记录自增开始的时间
long begin = System.currentTimeMillis();
long a = 0;
for (int i = 0; i < count; i++) {
a++;
}
long b = 0;
for (int i = 0; i < count; i++) {
b++;
}
//记录自增结束的时间
long end = System.currentTimeMillis();
System.out.println("花费时间:" + (end - begin) + "ms");
}
public static void concurrency() throws InterruptedException {
long begin = System.currentTimeMillis();
Thread t1 = new Thread(() -> {
long a = 0;
for (int i = 0; i < count; i++) {
a++;
}
});
t1.start();
Thread t2 = new Thread(() -> {
long b = 0;
long a = 0;
for (int i = 0; i < count; i++) {
b++;
}
});
t2.start();
t1.join();//让main线程等待t1线程执行结束
t2.join();//让main线程等待t2线程执行结束
long end = System.currentTimeMillis();
System.out.println("多线程花费的时间:" + (end - begin));
}
public static void main(String[] args) throws InterruptedException {
//serial();
concurrency();
}
}
虽然这里我们使用多线程效率提高了,但这也是适合数据计算比较多的情况下。如果数据很少,我们就没必要使用多线程,因为创建多线程也是需要花费时间和空间的。因此使用多线程的时候还要看适用场景。
方法 | |
Thread() | 创建线程对象 |
Thread(Runnable target) | 使用 Runnable 对象创建线程对象 |
Thread(String name) | 创建线程对象,并命名 |
Thread(Runnable target, String name) | 使用 Runnable 对象创建线程对象,并命名 |
Thread(ThreadGroup group,Runnable target) | 线程可以被用来分组管理,分好的组即为线程组,这个目前我们了解即可 |
因此run()只是一个普通方法,描述一个任务的内容,而且是串行执行,不创建线程。而start()才创建线程。
文章浏览阅读285次。摘要:本文介绍了使用 ChatGPT 和隐写术生成恶意软件的方法、所带来的威胁和风险,以及针对这种方法的防范措施。优化和混淆恶意软件代码:为降低被检测到的风险,攻击者可能会修改代码的结构和变量名,使得恶意生成的恶意软件可能被用于进行针对性或大规模的网络攻击,给个人和组织带来巨大的经济损失和声誉损害。摘要:本文探讨了使用 ChatGPT 和隐写术生成恶意软件的威胁和风险,以及为应对这些威胁和风险而采取的防范措施。摘要:本文讨论了使用 ChatGPT 和隐写术生成恶意软件的威胁和风险,以及一些可能的防范措施。_隐写术的新闻
文章浏览阅读1.4w次,点赞10次,收藏17次。例如我把图例移到中间,则:> barplot(counts,beside=TRUE,col=c("red","green","yellow"),legend=rownames(counts),main="条形图",xlab="处理方式",ylab="频数",args.legend=c(x=5.4,y=28.7))args.legend=c(x=,y=)如果不知道x 和y 的具体位置,可使用_bar如何控制图例位置
文章浏览阅读1.2w次,点赞6次,收藏30次。vue3引入router详解,vue3+typescript使用Vue-Router包详解。_vue3 router-view
文章浏览阅读911次。CMake Tutorial 跟我一起学_build_interface
文章浏览阅读1.4w次,点赞26次,收藏190次。内容主要基于B站狂神老师的Docker基础视频与部分网络docker博客总结,按照个人理解所整理总结。PDF需要的自取:https://yxmiaoyu.lanzouu.com/b01dm3ehg密码:1234_b站狂神
文章浏览阅读680次。 CSS基础学习现在web开发人员如果不知道CSS那就太落伍了,不过知道不等于会使用,更不等于精通。而我刚好属于那个知道CSS是干什么的,仅此而已的一员。CSS:Cascading Style Sheet,层叠样式表,可以将网页的大部分甚至全部的表示信息从HTML文件中移出,达到表现信息和核心内容相分离,达到易于维护以及美工和程序员分工更加明确的好处。这么好的东西是怎么应用到网页上面的呢?我们先来_css 打印样式和正常样式区分
文章浏览阅读3.4k次。下载地址https://download.docker.com/linux/static/stable/x86_64/docker-20.10.9.tgz解压到/usr/local/yeqiang@yeqiang-PC:/usr/local/docker$ ll总用量 200848-rwxr-xr-x 1 root staff 33908392 2022-03-14 09:47:07 containerd-rwxr-xr-x 1 root staff 6508544 2022-03-_devmapper not configured
文章浏览阅读1w次。上一篇已经讲了微服务组件中的 分布式配置中心,本章讲述 由JAVA编写的服务路由网关Zuul…_java cloud的路由叫什么
文章浏览阅读1.3w次。layui.use('form', function(){ var form = layui.form ,layer =layui.layer; //监听短信开关 form.on('switch(alert_sms)', function(data){ var index_sms; var alert_value =this.checked ? '1'_layui-form-switch 触发ajax事件
文章浏览阅读811次。NumPy的函数是一个非常有用的函数,可以用来重复数组中的元素。本文详细介绍了函数的用法,包括扁平化重复操作和按轴重复操作。我们还提供了相应的源代码示例,希望能帮助读者更好地理解和使用函数。_python np.repeat
文章浏览阅读1k次。1、先安装chrome浏览器下载一个chrome,进行正常安装即可,本人chrome版本为92,下载插件一定要最新版本1.1以上;2、再安装postman从官网下载了一个新最的进行正常安装(本人的太老了,取了最新版本postman)3、在chrome中添加插件interceptor下载地址:https://www.crx4chrome.com/crx/560/下载文件名为aicmkgpgakddgnaphhhpliifpcfhicfo-1.1.2-Crx4Chrome.c.._mac postman interceptor
文章浏览阅读263次。前言上篇已经详细提及到redis实现的redLock算法下的分布式锁,在项目里出现的问题以及提出的解决的方案,现在就针对这个分布式锁的话题,这节就针对zk的锁来详细说明,项目里使用的zk实现分布式锁还是很方便的,使用起来比redis要高效,安全。而且ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件..._zoomkeeper 与redis