我们知道我们打开个程序(或者说运行一款软件)其实也就是创建了一个进程,只不过程序是静态指令的集合,而进程是正在系统中运行的指令集合,进程是系统进行资源分配与调度的一个独立单位。进程具有独立性,动态性,并发性。现在的操作系统都支持并发,但在具体实现的细节上,根据硬件和操作系统的不同存在不同的策略,比较常用的方式有:共用式的多任务操作策略,抢占式的多任务策略。

线程扩展了进程的概念,线程是进程的执行单元,线程在进程中也是独立存在的,是一种并发的执行流,当进程被初始化之后,主线程就被创建出来了。对于绝大多数程序来说只有一个主线程,我们可以同时创建多条线程顺序执行流也就是线程。也就是说线程是进程的组成部分,一个进程可以拥有多个线程,一个线程必须有一个父进程。线程可以拥有自己的堆栈,自己的计数器,自己的局部变量等。但他们不在拥有系统资源,而是与其他线程之间共享该进程所拥有的所有的资源。线程用来完成一定的任务,可与其他线程之间共享父进程中的共享变量及部分环境,相互之间协同来完成进程所要完成的工作。

简单来说:一个程序运行后至少有一个进程,一个进程里可以包含多个线程,但至少包含一个线程。

线程的创建和启动:

Java使用Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例,每条线程的任务就是完成一定的任务,实际就是执行一段程序流,而java使用run方法来封装这段程序流。接下来介绍两种创建线程的方法。

第一种继承Thread类来创建线程类:

1、定义Thread类的子类,并重写Thread类的run方法,这个run方法的方法体就代表了线程需要完成的任务,就是线程执行体了。

2、创建Thread类子类的实例,也就是创建线程对象。

3、用线程的start方法来启动线程。

下面是一个具体的例子:

/**
*
*/
package cn.wan;
/**
* @author Administrator
*
*/
public class TestHread extends Thread{ private int i; public void run()
{
for(;i<20;i++)
{
System.out.println(getName()+""+i);
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub for(int i = 0;i<100;i++)
{
System.out.println(Thread.currentThread().getName()+""+i);
if(i== 20)
{
new TestHread().start();
System.out.println("AAAAAAAAAAAAAAAAAAAAAAAAAA");
new TestHread().start();
}
}
} }

当Java程序运行时,至少会创建一个线程,那就是主线程,主线程的线程执行体不是由run方法来确定的,而是由main方法来确定的。main方法的方法体代表主线程的线程执行体。

第二种实现Runnable接口创建线程类

1、定义Runnable接口的实现类并重写该接口的run方法,该run方法的方法体同样是该线程的线程执行体。

2、创建Runnable实现类的实例,并以此实例来作为Thread类的target来创建Thread对象。这个Thread类的实例才是真正的线程对象。

//   创建Runnable接口实现的对象,SecondThread类实现了这个接口,
SecondThread st = new SecondThread();
Thread th = new Thread(st);

下面是一个具体有的例子:

package cn.wan;

public class SecondThread implements Runnable{

    private int i;
@Override
/**
* run方法同样是线程的执行体
*/
public void run() {
// TODO Auto-generated method stub
for(;i<100;i++)
{
// 当线程类实现Runnable接口时
// 如果想获得当前线程,只能用Tread.currentThread()方法
System.out.println(Thread.currentThread().getName()+""+i);
} } /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub for(int i = 0;i<100;i++)
{
System.out.println(Thread.currentThread().getName()+""+i);
if(i== 20)
{
SecondThread st = new SecondThread();
// 通过new Thread(target,name)方法创建新线程
new Thread(st,"first one").start();
System.out.println("AAAAAAAAAAAAAAAAAAAAAAAAAA");
new Thread(st,"second one").start();
}
}
}
}

第一种和第二种方法主要差别在:

第一种

劣势:因为线程类已经继承了Thread类,所以不能再继续继承父类。

优势:编写简单,如果需要访问当前进程只需使用this关键字即可。无需使用Thread.currentThread方法。

第二种

劣势:编写复杂,如果需要访问当前线程需要使用Thread.currentThread方法。

优势:线程类只是继承了Runnable接口,还可以继承其他类。同时多线程可以同时共享同一个target对象,所以非常适合多个相同线程来处理同一份资源的情况。

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. Oracle密码过期设置和修改密码问题

    Oracle密码过期设置和修改密码问题 学习了:https://jingyan.baidu.com/article/ce09321b5608612bff858ff3.html sqlplus / as ...

  2. [Backbone] Verying Views

    Below we have our AppointmentsView instance rendering and then taking the rendered HTML and insertin ...

  3. JS中关于in运算符的问题

    转自:http://bbs.bccn.net/thread-412608-1-1.html in运算符 in运算符虽然也是一个二元运算符,但是对运算符左右两个操作数的要求比较严格.in运算符要求第1个 ...

  4. 12款程序员们最爱的Bootstrap模板

    如果你还没有开始使用Bootstrap模板,那你可真是有够OUT,这是一个帮助你快速开发的工具,Bootstrap是基于jQuery框架开发的,它在jQuery框架的基础上进行了更为个性化和人性化的完 ...

  5. 《C++游戏开发》十六 游戏中的寻路算法(二):迷宫&A*算法基础

    本系列文章由七十一雾央编写,转载请注明出处.  http://blog.csdn.net/u011371356/article/details/10289253 作者:七十一雾央 新浪微博:http: ...

  6. “最大子序列和”算法 java

    maxSubSum各自是最大子序列和的4中java算法实现. 第一种算法执行时间为O(N^3),另外一种算法执行时间为O(N^2),第三种算法执行时间为O(nlogn),第四种算法执行时间为线性N p ...

  7. 转:Python yield 使用浅析

    初学 Python 的开发者经常会发现很多 Python 函数中用到了 yield 关键字,然而,带有 yield 的函数执行流程却和普通函数不一样,yield 到底用来做什么,为什么要设计 yiel ...

  8. [Python]网络爬虫(九):百度贴吧的网络爬虫(v0.4)源码及解析

    转自:http://blog.csdn.net/pleasecallmewhy/article/details/8934726 百度贴吧的爬虫制作和糗百的爬虫制作原理基本相同,都是通过查看源码扣出关键 ...

  9. 项目中用到的ext及js细节

    1.js中无replaceAll方法,但能够用replace(regex," "),第一个參数是正則表達式,第二个參数是string,eg:str.replace(/\r\n/g, ...

  10. 使用Qt Creator 2.60编写C/C++程序

    使用Qt Creator 2.60编写C/C++程序(Windows7-64bit和Ubuntu12.10-64bit). 一.Windows7-64bit +MinGW: 从官网下载qt creat ...