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的多线程的更多相关文章

  1. Java的多线程机制系列:不得不提的volatile及指令重排序(happen-before)

    一.不得不提的volatile volatile是个很老的关键字,几乎伴随着JDK的诞生而诞生,我们都知道这个关键字,但又不太清楚什么时候会使用它:我们在JDK及开源框架中随处可见这个关键字,但并发专 ...

  2. java之多线程 二

    线程的生命周期: 当线程被创建并被启动时,它既不是一启动就进入了执行状态,在线程的生命周期中,它要经过new(新建),就绪(Runnable),运行(Running),阻塞(Blocked),dead ...

  3. Java的多线程机制系列:(一)总述及基础概念

    前言 这一系列多线程的文章,一方面是个人对Java现有的多线程机制的学习和记录,另一方面是希望能给不熟悉Java多线程机制.或有一定基础但理解还不够深的读者一个比较全面的介绍,旨在使读者对Java的多 ...

  4. Java Thread 多线程 介绍

    1.线程概述 几乎所有的操作系统都支持同时运行多个任务,一个任务通常就是一个程序,每个运行中的程序就是一个进程. 当一个程序运行时,内部可能包含了多个顺序执行流,每个顺序执行流就是一个线程. 2.线程 ...

  5. Java:多线程<一>

    程序运行时,其实是CPU在执行程序的进程,为了提高工作效率一个进程可以有多个线程. Java的多线程: 其实我们之前就见过Java的线程,main就是Java的一个线程,还有另一个条线程总是和main ...

  6. Java的多线程机制系列:(四)不得不提的volatile及指令重排序(happen-before)

    一.不得不提的volatile volatile是个很老的关键字,几乎伴随着JDK的诞生而诞生,我们都知道这个关键字,但又不太清楚什么时候会使用它:我们在JDK及开源框架中随处可见这个关键字,但并发专 ...

  7. Java的多线程机制系列:(三)synchronized的同步原理

    synchronized关键字是JDK5之实现锁(包括互斥性和可见性)的唯一途径(volatile关键字能保证可见性,但不能保证互斥性,详细参见后文关于vloatile的详述章节),其在字节码上编译为 ...

  8. Java基础——多线程

    Java中多线程的应用是非常多的,我们在Java中又该如何去创建线程呢? http://www.jianshu.com/p/40d4c7aebd66 一.常用的有三种方法来创建多线程 新建一个类继承自 ...

  9. JAVA之多线程的创建

    转载请注明源出处:http://www.cnblogs.com/lighten/p/5967853.html 1.概念 老调重弹,学习线程的时候总会牵扯到进程的概念,会对二者做一个区分.网上有较多的解 ...

  10. Java基础--多线程的方方面面

    1,什么是线程?线程和进程的区别是什么? 2,什么是多线程?为什么设计多线程? 3,Java种多线程的实现方式是什么?有什么区别? 4,线程的状态控制有哪些方法? 5,线程安全.死锁和生产者--消费者 ...

随机推荐

  1. 【转】【VS Code】配置文件Launch及快捷键

     Ctrl+shift+p,然后输入launch,点击第一个选项即可配置. 之后选择More即可 具体配置可修改为: { "version": "0.2.0", ...

  2. 使 Finder 显示 文件夹路径

    显示路径: cd ~ defaults write com.apple.finder _FXShowPosixPathInTitle -bool TRUE killall Finder 不显示路径: ...

  3. 性能优化系列二:JVM概念及配置

    一.虚拟机组成 虚拟机主要由三部分组成:编译器(执行引擎),堆与栈. 1. 编译器 编译器分为即时编译器与解释器. 即时编译器将代码编译成本地代码存于code区.因此它快,但它有内存限制! 解释器逐行 ...

  4. Java如何打印异常的堆栈?

    在Java编程中,如何打印异常的堆栈? 此示例显示如何使用异常类的printStack()方法打印异常的堆栈. package com.yiibai; public class PrintStackT ...

  5. 采用MiniProfiler监控EF与.NET MVC项目

    今天来说说EF与MVC项目的性能检测和监控 首先,先介绍一下今天我们使用的工具吧. MiniProfiler~ 这个东西的介绍如下: MVC MiniProfiler是Stack Overflow团队 ...

  6. HttpURLConnection如何添加请求头?

    1.conn.setRequestProPerty(name,value),两个参数都是字符串.... 2.用httpURLConnection的setRequestProPerty(name,val ...

  7. Python自然语言处理学习——jieba分词

    jieba——“结巴”中文分词是sunjunyi开发的一款Python中文分词组件,可以在Github上查看jieba项目. 要使用jieba中文分词,首先需要安装jieba中文分词,作者给出了如下的 ...

  8. Mac下给SD卡烧录树莓派系统

    1.mac 磁盘工具 抹掉sd卡 为fat 2. df -h 看清sd卡号 3. 卸载sd卡 diskutil unmount /dev/disk2s2 Volume UNTITLED on disk ...

  9. Struts2+Hibernate+Spring(SSH)三大框架整合jar包

    Struts2 + Spring3 + Hibernate3 框架整合 1. 每个框架使用 (开发环境搭建 )* 表现层框架 struts2 1) jar包导入: apps/struts2_blank ...

  10. geoserver 数据图层输出格式

    1.WMS服务请求参数 一般WMS的请求地址如下: http://localhost:8080/geoserver/topp/wms?service=WMS&versi on=1.1.0&am ...