1、多线程概述

当一个程序运行时,内部可能包含了多个顺序执行流,每个顺序执行流就是一个线程。主要以下几个优点:

  • 线程之间很容易实现共享内存
  • 创建线程代价较小
  • Java语言内置多线程功能支持

2、线程的创建和启动

所有的线程对象都是Thread类或其子类的对象,每一个线程完成一定的任务。
Java定义了两种创建线程的方法:
方法一:继承Thread类创建线程类

Ø  定义Thread的子类,并重写run方法

Ø  创建Thread子类的实例,即创建了线程对象

Ø  用线程对象的start方法来启动该线程

 1 public class DemoThread extends Thread
2 {
3 private int i;
4 String name;
5 public DemoThread(String name)
6 {
7 super(name);
8 }
9 public void run()
10 {
11 for(;i<100;i++)
12 System.out.println(Thread.currentThread().getName()+"-------"+i);
13
14 }
15 public static void main(String[] args)
16 {
17 for(int i=0;i<100;i++)
18 {
19 System.out.println(Thread.currentThread().getName()+"-----------"+i);
20
21 if(i==20)
22 {
23 new DemoThread("windows1").start();
24 new DemoThread("windows2").start();
25 }
26 }
27 }
28 }

方法二:实现Runnable接口创建线程类

Ø  定义Runnable接口的实现类,并重写该接口的run方法(该方法是该线程的线程执行体)

Ø  创建Runnable实现类的实例,并以此实例作为Thread的target来创建Tread对象

 1 public class DemoThread implements Runnable
2 {
3 private int i;
4 public void run()
5 {
6 for(;i<100;i++)
7 System.out.println(Thread.currentThread().getName()+"-------"+i);
8
9 }
10 public static void main(String[] args)
11 {
12 for(int i=0;i<100;i++)
13 {
14 System.out.println(Thread.currentThread().getName()+"-----------"+i);
15
16 if(i==20)
17 {
18 DemoThread t=new DemoThread();
19 new Thread(t,"Windows1").start();
20 new Thread(t,"Windows2").start();
21 }
22 }
23 }
24 }

两种方法比较:

  1. 采用实现Runnable接口方式的线程还可以继承其他类,而继承Tread类后不能再继承其他父类。
  2. 实现Runnable接口方式的线程可以共享一个target对象,适合多个相同线程来处理同一份资源的情况
  3. 若需要访问当前线程,实现Runnable接口方式只能使用Thread.currentThread()方法,而继承Thread可直接使用this即获取当前线程。

3、线程的生命周期

线程被创建并启动以后要经历五种状态,分别是新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Dead)。

新建:使用关键字new创建一个线程后,处于新建状态,此时仅由虚拟机为其分配内存并初始化成员变量,程序不会执行线程执行体。

就绪:当线程对象调用start()方法后,该线程处于就绪状态,虚拟机为其创建调用栈和程序计数器,但是此时线程并没有运行,只是表示线程可以运行了。
运行:当处于就绪状态的线程获得了CPU,开始执行run方法,则该线程处于运行状态。
阻塞:当发生线程调用sleep方法、阻塞式IO方法、suspend方法、等待通知(notify),线程将近阻塞状态。阻塞状态在合适的时候会重新进入就绪状态。
死亡:线程会以以下三种方式结束,然后就处于死亡状态,run方法执行完成、线程抛出未捕获的异常、直接跳跃stop方法结束进程。
 

4、线程的控制

isAlive():测试线程是否处于活动状态
isDaemo():测试进程是否为守护进程
join():等待该进程终止
sleep():在指定的毫秒数内让正在执行的线程休眠,该线程不丢失任何监视器的所属权
yield():暂停当前正在执行的线程对象,并执行其他线程,它是将线程转入就绪状态
setPriority(int newPriority):更改线程的优先级

5、线程的同步

当两个或多个线程需要访问同一共享资源时,需要某种方式来确保资源在某一时刻只被一个线程使用,这个方式称为“同步“。

为了解决同步问题,java引入同步监视器,代码块格式如下:

synchronized (obj)
{
}

Java还使用Synchronized关键字来修饰某个方法,此方法就无需显示指定同步监视器。
同步锁:它具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大。 使用Lock对象的代码格式如下:

 1 public class X
2 {
3 private final ReentrantLock lock=new ReentrantLock();
4 public void m()
5 {
6 lock.lock();//加锁
7 try
8 {
9 //需要保证线程安全的代码
10 }
11 finally
12 {
13 lock.unlock();//释放锁
14 }
15 }
16 }
17
 

6、线程的通信

Java为了避免轮询检测,通过wait()、notify()和notifyAll()方法实现进程内通信的机制。
wait():告诉调用线程放弃监控器进入等待模式直到其他线程进入同一监控器并调用notify()方法。
notify():唤醒在此同步器上等待的单个线程
notifyAll():唤醒在此同步器上等待的所有线程

7、线程池

线程池在系统启动时就创建大量空闲的线程,程序将一个Runnable对象传给线程池,线程池就会启动一个线程来执行该对象的run方法,当run方法执行结束后该线程不会死亡,而是再次返回线程池中称为空闲状态的,等待执行下一个Runnable对象的run方法。
使用线程池来执行线程任务的步骤如下:
  • 调用Executors类的静态工厂方法创建一个ExecutorService对象,该对象代表一个线程池。
  • 创建Runnable实现类或Callable实现类的实例,作为线程执行任务。
  • 调用ExecutorService对象的submit方法提交Runnable实例或Callable实例。
  • 当不想提交任何任务时调用ExecutorService对象的shutdown方法来关闭线程池。
eg:
 1 class TestThread implements Runnable
2 {
3 public void run()
4 {
5 for(int i=0;i<50;i++)
6 {
7 System.out.println(Thread.currentThread().getName()+"---"+i);
8 }
9 }
10 }
11 public class TestMain
12 {
13
14 public static void main(String[] args)
15 {
16 // TODO 自动生成的方法存根
17 TestThread t=new TestThread();
18 ExecutorService pool=Executors.newFixedThreadPool(6);
19 pool.submit(new Thread(t));
20 pool.submit(new Thread(t));
21 pool.shutdown();
22 }
23
24 }

执行结果:

 
转载自:http://www.cnblogs.com/xujian2014/p/4431350.html

Java中的多线程总结(转)的更多相关文章

  1. Java 中传统多线程

    目录 Java 中传统多线程 线程初识 线程的概念 实现线程 线程的生命周期 常用API 线程同步 多线程共享数据的问题 线程同步及实现机制 线程间通讯 线程间通讯模型 线程中通讯的实现 @(目录) ...

  2. Java中使用多线程、curl及代理IP模拟post提交和get访问

    Java中使用多线程.curl及代理IP模拟post提交和get访问 菜鸟,多线程好玩就写着玩,大神可以路过指教,小弟在这受教,谢谢! 更多分享请关注微信公众号:lvxing1788 ~~~~~~ 分 ...

  3. 【转】Java中的多线程学习大总结

    多线程作为Java中很重要的一个知识点,在此还是有必要总结一下的. 一.线程的生命周期及五种基本状态 关于Java中线程的生命周期,首先看一下下面这张较为经典的图: 上图中基本上囊括了Java中多线程 ...

  4. Java中的 多线程编程

    Java 中的多线程编程 一.多线程的优缺点 多线程的优点: 1)资源利用率更好2)程序设计在某些情况下更简单3)程序响应更快 多线程的代价: 1)设计更复杂虽然有一些多线程应用程序比单线程的应用程序 ...

  5. java中的多线程 // 基础

    java 中的多线程 简介 进程 : 指正在运行的程序,并具有一定的独立能力,即 当硬盘中的程序进入到内存中运行时,就变成了一个进程 线程 : 是进程中的一个执行单元,负责当前程序的执行.线程就是CP ...

  6. Java中的多线程=你只要看这一篇就够了

    如果对什么是线程.什么是进程仍存有疑惑,请先Google之,因为这两个概念不在本文的范围之内. 用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现.说这个话其 ...

  7. Android学习记录(5)—在java中学习多线程下载之断点续传②

    在上一节中我们学习了在java中学习多线程下载的基本原理和基本用法,我们并没有讲多线程的断点续传,那么这一节我们就接着上一节来讲断点续传,断点续传的重要性不言而喻,可以不用重复下载,也可以节省时间,实 ...

  8. Java中使用多线程、curl及代理IP模拟post提交和get訪问

    Java中使用多线程.curl及代理IP模拟post提交和get訪问 菜鸟,多线程好玩就写着玩.大神能够路过不吝赐教.小弟在这受教.谢谢! 很多其它分享请关注微信公众号:lvxing1788 ~~~~ ...

  9. Java中的多线程技术全面详解

    本文主要从整体上介绍Java中的多线程技术,对于一些重要的基础概念会进行相对详细的介绍,若有叙述不清晰或是不正确的地方,希望大家指出,谢谢大家:) 为什么使用多线程 并发与并行 我们知道,在单核机器上 ...

  10. 详细分析 Java 中实现多线程的方法有几种?(从本质上出发)

    详细分析 Java 中实现多线程的方法有几种?(从本质上出发) 正确的说法(从本质上出发) 实现多线程的官方正确方法: 2 种. Oracle 官网的文档说明 方法小结 方法一: 实现 Runnabl ...

随机推荐

  1. myeclipse svn

    打开myeclipse的help---install from site 点击add弹出对话框 在输入框中输入对应内容 http://subclipse.tigris.org/update_1.10. ...

  2. 53个要点提高php效率

    用单引号代替双引号来包含字符串,这样做会更快一些.因为PHP会在双引号包围的字符串中搜寻变量,单引号则不会,注意:只有echo能这么做,它是一种可以把多个字符串当作参数的“函数”(译注:PHP手册中说 ...

  3. 自己在安装centos 系统时, 是使用英文安装 成功,现在系统语言为英语,如何设置为中文?

    作为一个linux菜鸟,遇到的问题可谓真多,在虚拟机VMware上安装好centos系统后,心里甚喜,也连上网络了. 一.遇到的问题 but,火狐浏览器浏览网页出现乱码,也不知道怎么解决?所有的中文都 ...

  4. CHAR 详解

    CHAR(20):20指的是表中的a字段能存储的最大字符个数 CREATE TABLE `a` ( `a` char(20) DEFAULT NULL) ENGINE=InnoDB DEFAULT C ...

  5. 使用vi是方向键变乱码 退格键不能使用的解决方法

    一.编辑/etc/vim/vimrc.tiny 由于/etc/vim/vimrc.tiny的拥有者是root用户,所以要在root的权限下对这个文件进行修改.很简单,这个文件里面的倒数第二句话是“se ...

  6. configure JDBCRealm JAAS for mysql and tomcat 7 with form based authentication--reference

    Hello all, In this tutorial we are going to configure JDBCRealm JAAS for tomcat 7 and mysql database ...

  7. 为什么你需要使用instancetype而不是id

    四年前Clang添加了关键字instancetype,目的在于取代-alloc和-init等方法的返回类型id,那么使用instancetype到底比id好在哪里? instancetype宣言 不管 ...

  8. nginx php7 配置 备用

    yum install epel-* -y yum install -y wget unzip gcc gcc-c++ make zlib zlib-devel pcre pcre-devel lib ...

  9. 11.3 afternoon

    迭代40 #include<cstdio> #include<cstring> using namespace std; int n,sum,falg; ],c[]; void ...

  10. java之log4j的配置

    java之log4j的配置 log4j有很多的优点,用起来很方便,就是配置起来有些麻烦,下面我介绍一下log4j的配置方法. log4j是用来记录日志的. 软件的运行过程离不开日志.日志主要用来记录系 ...