Java多线程及其使用(一)

Java多线程对我来说一直是个高级而且神秘的东西,那么今天有幸也正好有时间讲解一下Java的多线程。

首先线程的概念及定义就不说了

1.创建线程三种方式:1.继承Thread 2.实现Runnable接口 3.实现Callable接口

继承Thread

public class FirstThread extends Thread{
	private int i;
	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());
			if(i == 20){
				new FirstThread().start();
				new FirstThread().start();
			}
		}
	}

}

实现Runnable

public class SecondThread implements Runnable{
	private int i;
	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){
				SecondThread st = new SecondThread();
				new Thread(st,"新线程1").start();
				new Thread(st, "新线程2").start();
			}
		}
	}

}

实现Callable

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

public class ThirdThread implements Callable<Integer>{
	public Integer call(){
		int i=0;
		for(;i<100;i++){
			System.out.println(Thread.currentThread().getName()+"的循环变量i的值"+i);
		}
		return i;
	}
	public static void main(String[] args){
		ThirdThread rt = new ThirdThread();
		FutureTask<Integer> task = new FutureTask<Integer>(rt);
		for(int i=0; i<100; i++){
			System.out.println(Thread.currentThread().getName()+"的循环变量i的值"+" "+i);
			if(i==20){
				new Thread(task, "有返回值的线程").start();
			}
		}
		try{
			System.out.println("子线程的返回值:"+task.get());
		}catch(Exception e){
			e.printStackTrace();
		}
	}

}

简单说明:Callable更像是Runnable的增强版,所以可以归为一类,所以大体上创建线程的方式只有两种,对于使用Thread方式好,还是Runnale方式好,这里推荐Runnale方法,因为如果采用继承Thread方法就不能继承其它父类,相比之下,Runnale则更加灵活

2.线程的生命周期(这里以网上收集的一幅图来说明)

3.线程的控制

(1)join()方法:作用是如果在运行当前线程的时候中途你又调用另一线程,那么当前线程先暂停执行,把另一线程执行完后在继续执行

(2)守护线程:作用是为其它线程提供服务,而且又在后台运行,所以又叫后台线程

(3)线程睡眠:使用sleep方法,可以理解为在睡眠这段时间内指定的线程都不会执行(就让它一直睡下去),即在指定时间内的线程无效(这是为了帮助理解,片面的说法)

(4)线程让步:使用yield方法,可以理解为在指定时间内指定的线程不执行,过了这段时间,在执行(只是暂停,目的是为了想让其它线程执行)

(5)优先级的设置:字面意思就可以理解,就不再阐述

4.线程的同步(意思就是线程按先后顺序依次执行)

试想如果线程不同步,就会出现不按顺序执行,就会出现线程同时执行,这样就会出大问题

如果多个线程异步(不同步)访问,就出问题了,比如典型的银行存款取款问题,这是类似生产者和消费者的问题(其实很简单,意思就是一个人赚钱一个人花钱),如果存款和取款同时操作,我们就会出现很多问题,比如作为取款方,系统要对取款进行钱的减量操作,但是另一个人又在存,而且同一时间,我的减量操作到底是存了后的还是存了前的?作为存款方,系统对存款进行增量操作,但是我的增量操作,到底是取了后的还是取了钱的,那么系统就会出问题了,那么银行要是这么搞,你会高兴还是悲伤呢,自己的钱老是出问题。

所以,多个线程访问同样资源时,我们要进行同步操作,同步操作有以下几种方式

(1).使用synchronized:可以对方法进行锁定,可以理解为,每个线程有一把钥匙,你执行这个方法,方法使用synchronized就会加锁,你要你的线程只有一个能到达锁前开锁,每个线程访问都会对该方法锁定;也可以对代码块锁定,大家都知道,函数方法就是代码写的,那么方法能锁定代码块也能锁定

对方法锁定

public synchronized void 方法名(锁定的参数(比如银行账户)){

方法的实现

}

对代码块的锁定

synchronized(锁定的参数(比如银行账户)){

代码的实现

}

(2).使用同步锁Lock:这个方法比synchronized更强大,主要体现在:更为广泛的锁定操作,因此实现起来更为灵活,比较好的东西也比较重要,但是使用方法差不多,所以这里不做详细介绍

4.2.死锁:是指两个或两个以上的线程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去(感觉不是很好理解,可以查阅相关资料)

5线程的通信,有以下几种方式

(1)对于synchronized借助Object类提供的wait(),notify,nitifyAll()三个方法,我们从字面意思就可以大体理解他们的作用

(2)如果使用Lock对象,则要使用Condition来控制,借助await(),signal,signalAll(),是不是感觉和synchronized的通信控制比较相似,那么我们也可以以字面意思来理解它们的大体作业

(3)使用阻塞队列(BlockingQueue),这是Java5提供的一个接口BlockigQueue,使用put(),take(),方法,

6.线程组,线程池,线程相关的工具ThreadLoacl及安全的线程集合(主要对不安全的集合进行包装,使之安全)以后再做介绍

最后是线程的使用:

我们学习了线程最为困惑的是什么时候我们使用多线程:

1.要处理的数据比较庞大(比如对数据库的数据进行分析)

2.并发控制,一般采用线程池技术

时间不够了,就暂时写到这里吧,写的不是很详细,有时间再补充上去,对了,这里推荐一个网站给大家吧,并发编程网,我感觉里面的东西非常好,所以有时间一定要去看看,如果你对多线程技术感兴趣的话

时间: 2024-11-03 03:25:42

Java多线程及其使用(一)的相关文章

Java多线程系列--“JUC锁”11之 Semaphore信号量的原理和示例

概要 本章,我们对JUC包中的信号量Semaphore进行学习.内容包括:Semaphore简介Semaphore数据结构Semaphore源码分析(基于JDK1.7.0_40)Semaphore示例 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3534050.html Semaphore简介 Semaphore是一个计数信号量,它的本质是一个"共享锁". 信号量维护了一个信号量许可集.线程可以通过调用acquire()来获取信号量的许可

从JAVA多线程理解到集群分布式和网络设计的浅析

对于JAVA多线程的应用非常广泛,现在的系统没有多线程几乎什么也做不了,很多时候我们在何种场合如何应用多线程成为一种首先需要选择的问题,另外关于java多线程的知识也是非常的多,本文中先介绍和说明一些常用的,在后续文章中如果有必要再说明更加复杂的吧,本文主要说明多线程的一下几个内容: 1.在应用开发中什么时候选择多线程? 2.多线程应该注意些什么? 3.状态转换控制,如何解决死锁? 4.如何设计一个具有可扩展性的多线程处理器? 5.多线程联想:在多主机下的扩展-集群? 6.WEB应用的多线程以及

java多线程心得

多并发的时候,在什么情况下必须加锁?如果不加锁会产生什么样的后果. 加锁的场景跟java的new thread和Runnable的关系是什么? 看看java的concurrentMap源码. 还有spring 的web.xml启动执行源码 spring aop http://www.cnblogs.com/FDROSE1001/p/3661895.html activemq的本质是什么? java的jms hibernate由配置文件映射到实体类的本质是什么? java反射 spring aop

Rhythmk 一步一步学 JAVA (21) JAVA 多线程

1.JAVA多线程简单示例 1.1 .Thread  集成接口 Runnable 1.2 .线程状态,可以通过  Thread.getState()获取线程状态: New (新创建) Runnable (可以运行) Blocked  (被阻塞) Waiting  (等待) Timed waiting (计时等待) Terminated  (被终止) ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27

(转载)Java多线程入门理解

转载出处http://blog.csdn.net/evankaka 写在前面的话:此文只能说是java多线程的一个入门,其实Java里头线程完全可以写一本书了,但是如果最基本的你都学掌握好,又怎么能更上一个台阶呢?如果你觉得此文很简单,那推荐你看看Java并发包的的线程池(Java并发编程与技术内幕:线程池深入理解),或者看这个专栏:Java并发编程与技术内幕.你将会对Java里头的高并发场景下的线程有更加深刻的理解. 目录(?)[-] 一扩展javalangThread类 二实现javalan

Java多线程系列--“JUC锁”02之 互斥锁ReentrantLock

ReentrantLock介绍 ReentrantLock是一个可重入的互斥锁,又被称为"独占锁". 顾名思义,ReentrantLock锁在同一个时间点只能被一个线程锁持有:而可重入的意思是,ReentrantLock锁,可以被单个线程多次获取.ReentrantLock分为"公平锁"和"非公平锁".它们的区别体现在获取锁的机制上是否公平."锁"是为了保护竞争资源,防止多个线程同时操作线程而出错,ReentrantLock在

synchronized与static synchronized 的差别、synchronized在JVM底层的实现原理及Java多线程锁理解

本Blog分为例如以下部分: 第一部分:synchronized与static synchronized 的差别 第二部分:JVM底层又是怎样实现synchronized的 第三部分:Java多线程锁,源码剖析 第一部分:synchronized与static synchronized的差别 1.synchronized与static synchronized 的差别 synchronized是对类的当前实例进行加锁,防止其它线程同一时候訪问该类的该实例的全部synchronized块.注意这里

深入聊聊Java多线程

一.背景 在没有学习Java多线程以前,总觉得多线程是个很神秘的东西,只有那些大神才能驾驭,新年假期没事就来学习和了解一下Java的多线程,本篇博客我们就来从头说一下多线程到底是怎么回事. 二.概述 1.进程的概念 每一个正在运行的程序都是一个进程,它是系统进行资源分配和调用的独立单位.且 每一个进程都有自己的内存空间和系统资源. 2.线程的概念 是进程中的单个顺序控制流,是一条执行路径.每个进程都可以拥有一个或者多个线程.各个线程之间都共享所属的那个进程的内存空间和系统资源. 3.单线程和多线

Java多线程 2 线程的生命周期和状态控制

一.线程的生命周期 线程状态转换图: 1.新建状态 用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态.处于新生状态的线程有自己的内存空间,通过调用start方法进入就绪状态(runnable). 注意:不能对已经启动的线程再次调用start()方法,否则会出现Java.lang.IllegalThreadStateException异常. 2.就绪状态 处于就绪状态的线程已经具备了运行条件,但还没有分配到CPU,处于线程就绪队列(尽管是采用队列形式,事实上,把它

Java 多线程

多线程作为Java中很重要的一个知识点,在此还是有必要总结一下的. 一.线程的生命周期及五种基本状态 关于Java中线程的生命周期,首先看一下下面这张较为经典的图: 上图中基本上囊括了Java中多线程各重要知识点.掌握了上图中的各知识点,Java中的多线程也就基本上掌握了.主要包括: Java线程具有五中基本状态 新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread(); 就绪状态(Runnable):当调用线程对象的start()方法(t