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,线程安全.死锁和生产者--消费者 ...
随机推荐
- Sword websocket分析二
//websocket发送数据 int send(uint8_t* message, uint64_t message_size) { //掩码 ] = { 0x12, 0x34, 0x56, 0x7 ...
- 简单MVVM教程
WPF+MVVM的本地桌面程序为背景,这样一来我们可以不去操心服务器那部分的事情,更加专注我们的MVVM.我打算把最重要的部分放到开头来讲,而接下来这最重要的部分却是全篇教程唯一没有代码的部分.好,下 ...
- 【原创】在VS2012中采用C++中调用DLL中的函数(4)
这两天因为需要用到VS2012来生成一个DLL代码,但是之前并没有用过DLL相关的内容,从昨天开始尝试调试DLL的文件调用,起初笔者在网络上找到了3片采用VSXXX版本进行调试的例子,相关的内容见本人 ...
- PHP CURL POST提交
$_post_url = 'http://XXXXX/XXX'; $post = 'key=12&content_id='.$content_id.'&md5='.$storeStat ...
- JDBC创建数据库实例
在本教程将演示如何在JDBC应用程序中创建数据库. 在执行以下示例之前,请确保您已经准备好以下操作: 具有数据库管理员权限,以在给定模式中创建数据库. 要执行以下示例,需要用实际用户名和密码替换这里用 ...
- e794. 创建JSlider组件
// Create a horizontal slider with min=0, max=100, value=50 JSlider slider = new JSlider(); // Creat ...
- wapp HTTP Error 404. The requested resource is not found.
原因: 本地80端口被占用,需要修改WAMP的默认端口 修改设置: 找到 bin/apache/apache***/conf/httpd.conf文件 将文件中的80修改为8088 修改这两个地方端口 ...
- PHP中全局变量的使用global和$GLOBALS[]
From: http://blog.csdn.net/happyqyt/article/details/7219889 用PHP开发项目,不可避免的会使用到全局变量,比如一些网站的配置信息,全站通用, ...
- asp.net MVC中防止跨站请求攻击(CSRF)的ajax用法
参考: Preventing Cross-Site Request Forgery (CSRF) AttacksValidating .NET MVC 4 anti forgery tokens in ...
- jQuery实现自动调用和触发某个事件的方法
1.比如我们通过jquery定义了一个点击事件,我们如何自动触发他: $(function(){ $('#button').click(function(){ alert('butto ...