Java的多线程
Java使用Thread代表线程,所有的线程对象都必须是Thread类或其子类的实例。每个线程的作用就是执行一段程序流(完成一定的任务)。
Java使用线程执行体来代表这段程序流。
1. 继承Thread类创建线程类
package org.apache;
public class ThreadDemo1 extends Thread {
private int i;
/*
* 重写run方法,也就是线程执行体
* 当线程类继承Thread类时,直接使用this即可取得当前线程
* 直接调用getName()方法即可返回当前线程的名字
*/
public void run(){
for ( ; i<100;i++){
System.out.println(getName() + " " + i);
}
}
public static void main(String[] args)
{
for (int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()
+ " "+i);
if(i==20){
//创建并启动第一个线程
new ThreadDemo1().start();
//创建并启动第二个线程
new ThreadDemo1().start();
}
}
}
}
执行结果:

注意:实际上该程序有三个线程,main()方法是主线程,显示的创建了两个子线程。
Thread-0和Thread-1 i的值是不连续的,所以Thread-0和Thread-1不能共享Thread类的实例变量。
2. 实现Runnable接口创建线程类
package org.apache;
public class ThreadDemo2 implements Runnable {
private int i;
//当实现Runnable接口时必须用Thread.currentThread().getName()获取当前线程
public void run() {
for ( ; i<100;i++){
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
public static void main(String[] args) {
for (int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName() + " "+i);
if (i==20){
ThreadDemo2 td = new ThreadDemo2();
//通过new Thread(target,name)方法创建线程
new Thread(td,"线程1").start();
new Thread(td,"线程2").start();
}
}
}
}
结果:

i的值是连续的,共享同一个线程类的实例变量(其实是线程的target类)
3.使用Callable和Future创建线程
FutureTask同时实现
Future接口--->接收call()方法的返回值
和Runnable接口--->可以作为Thread的target
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask; /*
* 创建并启动有返回值的线程步骤:
* 1. 创建Callable接口的实现类,并实现call()方法,作为线程执行体
* 2. 使用FutureTask类包装Callable对象,该FutureTask对象封装了Callable对象的call()方法
* 3. 使用FutureTask对象作为Thread对象的target创建并启动新线程
* 4. 调用FutureTask对象的get()方法获得子线程的执行结束的返回值
*/
public class ThreadDemo3 implements Callable{
private int i; public Object call() throws Exception {
for ( ; i<100;i++){
System.out.println(Thread.currentThread().getName() + " " + i);
}
return i;
} public static void main(String[] args) {
ThreadDemo3 td = new ThreadDemo3();
//通过new Thread(target,name)方法创建线程
FutureTask<Integer> task = new FutureTask<Integer>(td);
for (int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName() + " "+i);
if (i==20){
new Thread(task,"有返回值的线程").start();
}
}
try {
//获取线程返回值
System.out.println(task.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
结果:

4. 控制线程
4.1 join线程
当程序程序执行流中调用其它线程的join()方法时,调用线程将会被阻塞。直到被join的线程执行完成。
package org.apache;
public class ThreadDemo1 extends Thread {
public ThreadDemo1 (String name){
super(name);
}
private int i;
/*
* 重写run方法,也就是线程执行体
* 当线程类继承Thread类时,直接使用this即可取得当前线程
* 直接调用getName()方法即可返回当前线程的名字
*/
public void run(){
for ( ; i<100;i++){
System.out.println(getName() + " " + i);
}
}
public static void main(String[] args) throws InterruptedException
{
new ThreadDemo1("新线程").start();
for (int i=0;i<100;i++){
Thread task = new ThreadDemo1("被join的线程");
System.out.println(Thread.currentThread().getName()
+ " "+i);
if(i==20){
//创建并启动第一个线程
task.start();
//main调用了join()方法,必须等task执行结束后才会向下执行
task.join();
}
}
}
}
执行结果:

分析可知main方法(主线程)被阻塞,只有新线程和join线程并发执行。
4.2 守护线程
有一种线程是为其它线程提供服务的(典型的有GC),被称为后台线程或者守护线程。
package org.apache;
public class ThreadDemo4 extends Thread{
private int i;
public void run(){
for (;i<1000;i++){
System.out.println(getName() + " "+i);
}
}
public static void main(String[] args) {
ThreadDemo4 task = new ThreadDemo4();
//设置为守护进程
task.setDaemon(true);
task.start();
for( int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+" "+i);
}
//程序执行到此处就main进程就结束了,JVM将会主动退出,守护线程也将被结束,无法执行到=999
}
}
执行结果:

4.3 线程睡眠:sleep
package org.apache;
import java.util.Date;
public class ThreadDemo5 {
//正在执行的线程将会暂停一段时间,进入阻塞状态
public static void main(String[] args) throws InterruptedException {
for (int i=0;i<10;i++){
System.out.println("当前时间: "+new Date());
Thread.sleep(1000);
}
}
}
结果:

Java的多线程的更多相关文章
- Java的多线程机制系列:不得不提的volatile及指令重排序(happen-before)
一.不得不提的volatile volatile是个很老的关键字,几乎伴随着JDK的诞生而诞生,我们都知道这个关键字,但又不太清楚什么时候会使用它:我们在JDK及开源框架中随处可见这个关键字,但并发专 ...
- java之多线程 二
线程的生命周期: 当线程被创建并被启动时,它既不是一启动就进入了执行状态,在线程的生命周期中,它要经过new(新建),就绪(Runnable),运行(Running),阻塞(Blocked),dead ...
- Java的多线程机制系列:(一)总述及基础概念
前言 这一系列多线程的文章,一方面是个人对Java现有的多线程机制的学习和记录,另一方面是希望能给不熟悉Java多线程机制.或有一定基础但理解还不够深的读者一个比较全面的介绍,旨在使读者对Java的多 ...
- Java Thread 多线程 介绍
1.线程概述 几乎所有的操作系统都支持同时运行多个任务,一个任务通常就是一个程序,每个运行中的程序就是一个进程. 当一个程序运行时,内部可能包含了多个顺序执行流,每个顺序执行流就是一个线程. 2.线程 ...
- Java:多线程<一>
程序运行时,其实是CPU在执行程序的进程,为了提高工作效率一个进程可以有多个线程. Java的多线程: 其实我们之前就见过Java的线程,main就是Java的一个线程,还有另一个条线程总是和main ...
- Java的多线程机制系列:(四)不得不提的volatile及指令重排序(happen-before)
一.不得不提的volatile volatile是个很老的关键字,几乎伴随着JDK的诞生而诞生,我们都知道这个关键字,但又不太清楚什么时候会使用它:我们在JDK及开源框架中随处可见这个关键字,但并发专 ...
- Java的多线程机制系列:(三)synchronized的同步原理
synchronized关键字是JDK5之实现锁(包括互斥性和可见性)的唯一途径(volatile关键字能保证可见性,但不能保证互斥性,详细参见后文关于vloatile的详述章节),其在字节码上编译为 ...
- Java基础——多线程
Java中多线程的应用是非常多的,我们在Java中又该如何去创建线程呢? http://www.jianshu.com/p/40d4c7aebd66 一.常用的有三种方法来创建多线程 新建一个类继承自 ...
- JAVA之多线程的创建
转载请注明源出处:http://www.cnblogs.com/lighten/p/5967853.html 1.概念 老调重弹,学习线程的时候总会牵扯到进程的概念,会对二者做一个区分.网上有较多的解 ...
- Java基础--多线程的方方面面
1,什么是线程?线程和进程的区别是什么? 2,什么是多线程?为什么设计多线程? 3,Java种多线程的实现方式是什么?有什么区别? 4,线程的状态控制有哪些方法? 5,线程安全.死锁和生产者--消费者 ...
随机推荐
- 关于Unity中物理检测的准备
1.要确定每个物体的碰撞类型,是有碰撞效果的碰撞还是没有碰撞效果的碰撞(is trigger),带不带刚体. 2.给每个物体分层,再设置哪些层会发生碰撞,哪些完全不产生碰撞. 3.给每个物体设置标记, ...
- Ajax+Jsp+servlet+json技术的使用
Ajax+Jsp+servlet+json技术的使用 在使用json的时候,记得必须导入如下几个.jar包,最好是手动复制.jar包只lib路径下,否则可能出现异常. commons-beanutil ...
- 解决git pull 每一次都需要输入密码的问题
方法1: 当我们配置好我们的git以后呢,我们可以在配置文件~/.gitconfig 或 ~/.config/git/config 文件里加入这么两行: [credential] helper = s ...
- VIM下的插入模式的相关知识:
1. 建议:当打错一个单词时,删除掉重新打一遍, 避免在错誤的基础上进行修改: 2. 在插入模式下,可以用一些组合键,它也可以用于VIM 命令模式下,也可以用于 base shell 下: ctrl- ...
- 第三百九十一节,Django+Xadmin打造上线标准的在线教育平台—404,403,500页面配置
第三百九十一节,Django+Xadmin打造上线标准的在线教育平台—404,403,500页面配置 路由映射在全局也就是根目录里的urls.py里配置404路由映射 注意:不是写在urlpatter ...
- Java如何处理空堆栈异常?
在Java编程中,如何处理空堆栈异常? 本例展示了如何使用Date类的System.currentTimeMillis()方法和Stack类的s.empty(),s.pop()方法来处理空堆栈异常. ...
- Git -- 工作区 和 暂存区
Git和其他版本控制系统如SVN的一个不同之处就是有暂存区的概念. 先来看名词解释. 工作区(Working Directory) 就是你在电脑里能看到的目录,比如我的learngit文件夹就是一个工 ...
- HTML5 3D Google搜索 小盒子 大世界
HTML5真是能让人想象万千,居然动起了Google搜索的主意,它利用HTML5技术将Google搜索放到了一个小盒子里,弄起了3D搜索.随着鼠标移动,HTML5 3D搜索盒子也就转动,非常立体.点击 ...
- u3d加载外部视屏
u3d的外部加载视屏,采用www方式,可以使用gui播放,也可以绑定到gameobject上作为动态材质使用,不过目前只支持.ogg格式,需要转... using UnityEngine;using ...
- dpkg: error processing package libraspberrypi-doc (--configure): package is in a very bad inconsistent state;
dpkg: error processing package libraspberrypi-doc (--configure): package is in a very bad inconsiste ...