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. WebForm Repeater的事件、后天数据展示--2017年1月8日

    Repeater的Command操作 1.ItemCommand事件 :在Repeater中所有能触发事件的控件,都会来触发这一个事件 CommandName : 判断点击的是什么按钮,e.Comma ...

  2. c#调用钩子

    1 概述 在c++中有钩子程序,但是在C#还没有对其进行封装,所以需要自己根据实际情况调用钩子.钩子在我的理解下是,通过初始化钩子与系统中消息映射建立某种关系,当点击鼠标或者键盘,就会通过钩子中的回调 ...

  3. VM网络无法连接--提示ethernet0无法连接到虚拟网络

    打开 “编辑->虚拟网络设置"里面,点“恢复默认” 如果还不行 然后 开网络和共享中心 左击  本地连接(若是无线网络,则点击无线网络连接)----属性----共享---- 在:允许其 ...

  4. IE浏览器中发送到onenote的选项没有调出来??

    最近使用onenote 作为笔记本,发现这个比word好用很多,特别是还有一个功能很好用,发送到onenote,可以选中网页中的内容,发送到onenote.但是有一些IE浏览器这个选项没有调出来,还是 ...

  5. “发送至Onenote”惹来的小麻烦(转)

    原文来自 :  http://blog.csdn.net/yiyu_0417/article/details/7864172 [看到这篇文章,我觉得以后我也会遇到这个问题,很有价值我就先拷贝了,留着以 ...

  6. java.lang.RuntimeException: Missing type parameter

    程序中用到了gson的new typeToken,结果打包成apk发布时,发现抛出异常,但不通过打包apk时发现一切正常,百思不得其解,最初怀疑没有将gson-1.7.1.JAR打包进去,后来经过测试 ...

  7. Avoid non-default constructors in fragments: use a default constructor plus Fragment#setArguments(Bundle) instead

    “Avoid non-default constructors in fragments: use a default constructor plus Fragment#setArguments(B ...

  8. Qt 学习之路:Qt 简介

    Qt 是一个著名的 C++ 应用程序框架.你并不能说它只是一个 GUI 库,因为 Qt 十分庞大,并不仅仅是 GUI 组件.使用 Qt,在一定程度上你获得的是一个“一站式”的解决方案:不再需要研究 S ...

  9. MapReduce计数器

    1.MapReduce计数器是什么? 计数器是用来记录job的执行进度和状态的.它的作用可以理解为日志.我们可以在程序的某个位置插入计数器,记录数据或者进度的变化情况. 2.MapReduce计数器能 ...

  10. hadoop文件的序列化

    目录 1.为什么要序列化? 2.什么是序列化? 3.为什么不用Java的序列化? 4.为什么序列化对Hadoop很重要? 5.Hadoop中定义哪些序列化相关的接口呢? 6.Hadoop 自定义Wri ...