多线程(三) java中线程的简单使用
java中,启动线程通常是通过Thread或其子类通过调用start()方法启动。
常见使用线程有两种:实现Runnable接口和继承Thread。而继承Thread亦或使用TimerTask其底层依旧是实现了Runnabel接口。考虑到java的单继承的限制,所以在开发过程中大部分情况在使用线程的时候是通过实现Runnabel接口或者Runnbel匿名类来实现的。
例如:
package com.zpj.thread.blogTest;
/**
* Created by PerkinsZhu on 2017/8/11 16:42.
*/
public class ThreadTest { public static void main(String[] args) {
ThreadTest threadTest = new ThreadTest();
//所有的这些启动方式的执行体都是在run方法中完成的
threadTest.testLambda();
threadTest.testRunnableWithAnonymousRunnable();
threadTest.testRunnableWithAnonymousThread();
threadTest.testRunnable();
threadTest.testMyThread();
} public void testLambda() {//lambda表达式开启线程 jdk1.8中的特性
new Thread(() -> System.out.println("i am lambda Thread....")).start();
} public void testRunnableWithAnonymousThread() {//匿名Thread类开启线程
new Thread() {
@Override
public void run() {
System.out.println("i am ThreadWithAnoymous");
}
}.start();
} public void testRunnableWithAnonymousRunnable() {//匿名Runnable类开启线程
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("i am RunableWithAnoymous");
}
});
thread.start();
} public void testRunnable() {//实现Runnable接口
MyRunnable runable = new MyRunnable();
Thread thread = new Thread(runable);
thread.start();
} public void testMyThread() {//继承自Thread
MyThread thread = new MyThread();
thread.setName("MyThread");
thread.start();
}
} class MyRunnable implements Runnable {//实现Runnable接口 @Override
public void run() {
System.out.println("i am MyRunnable");
}
} class MyThread extends Thread {//继承Thread @Override
public void run() {
System.out.println(" i am MyThread!!");
}
}
注意,直接调用run()方法的方式执行线程体并未开启新线程,只是在main方法中调用了一个普通方法而已。而使用start()方法则会开启一个新的线程执行。两者的区别主要表现在前者是阻塞式的,而后者为非阻塞式。
例如:
public void testStartAndRun(){
MyThread thread = new MyThread();
thread.setName("MyThread");
thread.start();//start启动两者异步非阻塞运行
while (true){
System.out.println("---- "+Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class MyThread extends Thread {//继承Thread
@Override
public void run() {
while(true){
System.out.println("=== "+Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
运行结果如下:
---- main
==== MyThread
---- main
==== MyThread
==== MyThread
---- main
==== MyThread
---- main
而把thread.start() 修改为thread.run();之后,则如下
==== main
==== main
==== main
==== main
==== main
==== main
这里之所以线程名称为main是因为是在main线程中调用的run方法,所以打印出来的是===main。而thread.run();语句下面的循环则永远不会执行,程序将会一直在run方法中循环下去。
那么调用start方法,程序都做了些什么呢?看一下底层实现。
public synchronized void start() {
//验证线程的状态
if (threadStatus != 0) {//这里的验证涉及到线程不能重复启动的问题,线程多次调用start则会抛出该异常
throw new IllegalThreadStateException();
}
//把该线程加入到线程组中
group.add(this);
boolean started = false;//标识线程是否启动成功
try {
start0();//调用native方法启动线程 该方法是阻塞的,程序等待其完成之后执行下面语句如果执行失败则直接抛出异常进入finally。
started = true;//修改线程启动状态
} finally {
try {
if (!started) {//启动失败,则移出线程组
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
}
}
}
private native void start0();//native方法启动线程
通过Runnable启动具有一定的局限,执行线程没有返回值,无法捕获异常。在有些特殊情况下需要线程返回结果的时候就不太合适。这时可以选择Callable接口来完成。Callable涉及到Future模型,这到后面再说。
=============================================
原文链接:多线程(三) java中线程的简单使用 转载请注明出处!
=============================================
-----end
多线程(三) java中线程的简单使用的更多相关文章
- Java中线程的使用 (2)-多线程、线程优先级、线程睡眠、让步、阻塞
Java中线程的使用 (2)-多线程.线程优先级.线程睡眠.让步.阻塞 (一)多线程使用方法 说明:创建每个新的线程,一定要记得启动每个新的线程(调用.start()方法) class Xc3 ext ...
- Java多线程并发03——在Java中线程是如何调度的
在前两篇文章中,我们已经了解了关于线程的创建与常用方法等相关知识.接下来就来了解下,当你运行线程时,线程是如何调度的.关注我的公众号「Java面典」了解更多 Java 相关知识点. 多任务系统往往需要 ...
- 沉淀再出发:java中线程池解析
沉淀再出发:java中线程池解析 一.前言 在多线程执行的环境之中,如果线程执行的时间短但是启动的线程又非常多,线程运转的时间基本上浪费在了创建和销毁上面,因此有没有一种方式能够让一个线程执行完自己的 ...
- 面试官:Java中线程是按什么顺序执行的?
摘要:Java中多线程并发的执行顺序历来是面试中的重点,掌握Java中线程的执行顺序不仅能够在面试中让你脱颖而出,更能够让你在平时的工作中,迅速定位由于多线程并发问题导致的"诡异" ...
- java中线程机制
java中线程机制,一开始我们都用的单线程.现在接触到多线程了. 多线性首先要解决的问题是:创建线程,怎么创建线程的问题: 1.线程的创建: 四种常用的实现方法 1.继承Thread. Thread是 ...
- 多线程(五) java的线程锁
在多线程中,每个线程的执行顺序,是无法预测不可控制的,那么在对数据进行读写的时候便存在由于读写顺序多乱而造成数据混乱错误的可能性.那么如何控制,每个线程对于数据的读写顺序呢?这里就涉及到线程锁. 什么 ...
- Java中线程池,你真的会用吗?
在<深入源码分析Java线程池的实现原理>这篇文章中,我们介绍过了Java中线程池的常见用法以及基本原理. 在文中有这样一段描述: 可以通过Executors静态工厂构建线程池,但一般不建 ...
- Java中线程和线程池
Java中开启多线程的三种方式 1.通过继承Thread实现 public class ThreadDemo extends Thread{ public void run(){ System.out ...
- Java中线程池,你真的会用吗?ExecutorService ThreadPoolExcutor
原文:https://www.hollischuang.com/archives/2888 在<深入源码分析Java线程池的实现原理>这篇文章中,我们介绍过了Java中线程池的常见用法以及 ...
随机推荐
- C#标识符
- typeahead + JDK 8 并行流 + redis 高速即时查询.
感谢JDK8,让我们JAVA 程序员暂时不用担心失业. 有些情况,需要根据用户输入值,即时查询数据库,MYSQL显然不再适合这种业务. mongoDB看似最适合,但是为了这么一个破功能,也不值得特意去 ...
- Jmeter简单介绍与搭配Jenkins实现自动化
Jmeter简介 Apache JMeter 是 Apache 组织开发的基于 Java 的压力测试工具.用于对软件做压力测试,它最初被设计用于 Web应用测试,但后来扩展到其他测试领域. 它可以用于 ...
- MSQL的基准测试
Mysql基准测试 基准测试 直接.简单.易于比较,用于评估服务器的处理能力 压力测试 对真实的月数据进行测试,获得真是系统所能承受的压力 基准测试的目的 1.建立MySQL服务器的性能基准线 2.模 ...
- linux iptables配置
防火墙硬件防火墙软件防火墙: 应用层防火墙 网络层防火墙:linux包过滤防火墙linux包过滤防火墙netfilter:位于linux内核中的包过滤功能体系,称为linux防火墙的"内核态 ...
- FC总线技术简介
FC是由美国标准化委员会(ANSI)的X3T11小组于1988年提出的高速串行传输总线,解决了并行总线SCSI遇到的技术瓶颈,并在同一大的协议平台框架下可以映射更多FC-4上层协议.FC具备通道和网络 ...
- Procedure execution failed 2013 - Lost connection to MySQL server during query
1 错误描述 Procedure execution failed 2013 - Lost connection to MySQL server during query 2 错误原因 由错误描述可知 ...
- 利用Eclipse中的Maven构建Web项目(二)
利用Eclipse中的Maven构建Web项目 1.新建源文件夹,Java Resources鼠标右键,"New-->Source Folder" 2.新建src/main/ ...
- jquery获取选中的文本和值
jquery获取选中的文本和值 1.说明 (1)获取select下拉框选中的索引 $("#selection").get(0).selectedIndex; (2)获取 ...
- CF368 D - Persistent Bookcase
re了20多发 还是我在测试数据上操作最后了10多发才发现的 其实只需要多加一句就好了 真的愚蠢啊,要不都能进前100了 #include<bits/stdc++.h> using nam ...