对线程的认知
2016-07-20 16:03
281 查看
一、线程的基本定义
众所周知,线程是Java语言的一个重要知识点,我们要了解线程首先就要了解线程的基本定义。线程顾名思义就是进程中的单一执行流,进程用于自己的独立空间,而线程只能共享进程的空间,一个进程可以包含多个线程。
二、多线程的优点以及线程同步的概念
前面我们已经了解了线程的基本定义,那么我们现在就来探讨一下线程有哪些优点以及线程同步到底有什么作用。
(1)多线程的优点:
1.多线程可以同步并发的执行多个任务,当程序某个功能部分在等待某些资源时,此时又不愿意因为等待而造成程序暂停,那么就可以创建另外的线程进行其他工作。
2.多线程可以最大限度的降低CPU的闲置时间,从而提高CPU的利用效率。
下面我们就举个例子说明一下:读书和听音乐,如果我们先读书在听音乐或者先听音乐再读书,那么这样我们的效率就会大打折扣。如果我们现在换成一边听音乐一边读书,那么效率就会提高很多,线程也是同样的道理。
(2)线程同步:
要了解线程同步,我们可以通过了解线程同步的两个基本模型来了解线程同步的作用,即“监视线程”通讯模型以及“生产/消费者”模型。
1.“监视线程”通讯模型:即同时多个独立线程在运行,运行状态有第三方监控线程全程监控,这种就叫做“监视线程”通讯模型。下面我们通过银行取钱系统了解一下,在这个系统中我们有两个线程即ATM机与窗口取钱,他们的时间以及操作的对象即账户都相同。
主函数
package 线程;
public class test {
public static void main(String[] args) {
Account acount=new Account(1000);
Consumer con1=new Consumer(acount, "ATM", 700);
Consumer con2=new Consumer(acount, "银行窗口", 700);
con1.start();
con2.start();
}
}账户取款:注意在这里面我用到了一个synchronized 关键字,它的作用是锁定当前对象及方法
<pre name="code" class="java">package 线程;
/**
*账户取款
* @author Administrator
*
*/
public class Account {
//额度属性
private int count;
public Account(int count){
this.count=count;
}
public int getmoney(int cash){
synchronized (this) {
if(count<cash){
return -1;
}
else{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
count=count-cash;
return count;
}
}
}
}
取款的线程
package 线程;
/**
* 取款的线程
* @author Administrator
*
*/
public class Consumer extends Thread{
private Account acount;
private String way;
private int cash;
public Consumer(Account acount,String way,int cash){
this.acount=acount;
this.way=way;
this.cash=cash;
}
public void run(){
int count=acount.getmoney(cash);
if(count==-1){
System.out.println("此次在"+way+"上操作失败,账户余额为"+count);
}
else{
System.out.println("此次在"+way+"上操作成功,账户余额为"+count);
}
}
}
最后的运行结果就是:此次在银行窗口上操作失败,账户余额为-1
此次在ATM上操作成功,账户余额为300
如果上面没有用到关键字synchronized 那么结果就会完全不同:
此次在ATM上操作成功,账户余额为-400
此次在银行窗口上操作成功,账户余额为300
很显然这是不行的,所以要达到我们预期的要求我们就必须要使用关键字synchronized
而且synchronized的位置要正确,千万不能放在if语句之后,不然就没有效果。
2.“生产/消费者”模型:在这里会用到方法wait()和notify(),他们的作用分别是等待和通知。
生产者
package 消费者;
import java.util.ArrayList;
public class Producter extends Thread{
private ArrayList<Bnanel> arry;
private int n=1;
public Producter(ArrayList<Bnanel> arry){
this.arry=arry;
}
public void run(){
while(true){
synchronized (arry) {
if(arry.size()>0){
try {
arry.wait();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
Bnanel bl=new Bnanel("香蕉的序号:"+n);
System.out.println("生产出香蕉型号为:"+bl.name);
n++;
arry.notify();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}消费者
<pre name="code" class="java">package 消费者;
import java.util.ArrayList;
public class Consumer extends Thread{
private ArrayList<Bnanel> arry;
public Consumer( ArrayList<Bnanel> arry){
this.arry=arry;
}
public void run(){
while(true){
synchronized (arry) {
if(arry.size()==0){
try {
arry.wait();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
Bnanel bl=arry.remove(0);
System.out.println("取出商品,商品的型号:"+bl.name);
arry.notify();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
产品
package 消费者;
public class Bnanel {
public String name;
public Bnanel(String name){
this.name=name;
}
}主函数
package 消费者;
import java.util.ArrayList;
public class text {
public static void main(String[] args) {
ArrayList<Bnanel> arry=new ArrayList<Bnanel>();
Producter pd=new Producter(arry);
Consumer cm=new Consumer(arry);
pd.start();
cm.start();
}
}最后的运行结果为:
生产出香蕉型号为:香蕉的序号:1
生产出香蕉型号为:香蕉的序号:2
生产出香蕉型号为:香蕉的序号:3
生产出香蕉型号为:香蕉的序号:4
生产出香蕉型号为:香蕉的序号:5
。。。。。。
三、线程的生命周期
线程的生命周期主要分为五个主要的部分,即新建、就绪、阻塞、运行、死亡。新建就是线程建立一个实例对象;就绪就是线程已经启动但等待CPU调用;阻塞就是由于主观或客观的原因,线程停止运行;运行就是线程获得CPU资源并且正在执行任务即run方法;死亡就是当线程执行完毕或由于其他原因不能运行就叫作线程的死亡。
众所周知,线程是Java语言的一个重要知识点,我们要了解线程首先就要了解线程的基本定义。线程顾名思义就是进程中的单一执行流,进程用于自己的独立空间,而线程只能共享进程的空间,一个进程可以包含多个线程。
二、多线程的优点以及线程同步的概念
前面我们已经了解了线程的基本定义,那么我们现在就来探讨一下线程有哪些优点以及线程同步到底有什么作用。
(1)多线程的优点:
1.多线程可以同步并发的执行多个任务,当程序某个功能部分在等待某些资源时,此时又不愿意因为等待而造成程序暂停,那么就可以创建另外的线程进行其他工作。
2.多线程可以最大限度的降低CPU的闲置时间,从而提高CPU的利用效率。
下面我们就举个例子说明一下:读书和听音乐,如果我们先读书在听音乐或者先听音乐再读书,那么这样我们的效率就会大打折扣。如果我们现在换成一边听音乐一边读书,那么效率就会提高很多,线程也是同样的道理。
(2)线程同步:
要了解线程同步,我们可以通过了解线程同步的两个基本模型来了解线程同步的作用,即“监视线程”通讯模型以及“生产/消费者”模型。
1.“监视线程”通讯模型:即同时多个独立线程在运行,运行状态有第三方监控线程全程监控,这种就叫做“监视线程”通讯模型。下面我们通过银行取钱系统了解一下,在这个系统中我们有两个线程即ATM机与窗口取钱,他们的时间以及操作的对象即账户都相同。
主函数
package 线程;
public class test {
public static void main(String[] args) {
Account acount=new Account(1000);
Consumer con1=new Consumer(acount, "ATM", 700);
Consumer con2=new Consumer(acount, "银行窗口", 700);
con1.start();
con2.start();
}
}账户取款:注意在这里面我用到了一个synchronized 关键字,它的作用是锁定当前对象及方法
<pre name="code" class="java">package 线程;
/**
*账户取款
* @author Administrator
*
*/
public class Account {
//额度属性
private int count;
public Account(int count){
this.count=count;
}
public int getmoney(int cash){
synchronized (this) {
if(count<cash){
return -1;
}
else{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
count=count-cash;
return count;
}
}
}
}
取款的线程
package 线程;
/**
* 取款的线程
* @author Administrator
*
*/
public class Consumer extends Thread{
private Account acount;
private String way;
private int cash;
public Consumer(Account acount,String way,int cash){
this.acount=acount;
this.way=way;
this.cash=cash;
}
public void run(){
int count=acount.getmoney(cash);
if(count==-1){
System.out.println("此次在"+way+"上操作失败,账户余额为"+count);
}
else{
System.out.println("此次在"+way+"上操作成功,账户余额为"+count);
}
}
}
最后的运行结果就是:此次在银行窗口上操作失败,账户余额为-1
此次在ATM上操作成功,账户余额为300
如果上面没有用到关键字synchronized 那么结果就会完全不同:
此次在ATM上操作成功,账户余额为-400
此次在银行窗口上操作成功,账户余额为300
很显然这是不行的,所以要达到我们预期的要求我们就必须要使用关键字synchronized
而且synchronized的位置要正确,千万不能放在if语句之后,不然就没有效果。
2.“生产/消费者”模型:在这里会用到方法wait()和notify(),他们的作用分别是等待和通知。
生产者
package 消费者;
import java.util.ArrayList;
public class Producter extends Thread{
private ArrayList<Bnanel> arry;
private int n=1;
public Producter(ArrayList<Bnanel> arry){
this.arry=arry;
}
public void run(){
while(true){
synchronized (arry) {
if(arry.size()>0){
try {
arry.wait();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
Bnanel bl=new Bnanel("香蕉的序号:"+n);
System.out.println("生产出香蕉型号为:"+bl.name);
n++;
arry.notify();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}消费者
<pre name="code" class="java">package 消费者;
import java.util.ArrayList;
public class Consumer extends Thread{
private ArrayList<Bnanel> arry;
public Consumer( ArrayList<Bnanel> arry){
this.arry=arry;
}
public void run(){
while(true){
synchronized (arry) {
if(arry.size()==0){
try {
arry.wait();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
Bnanel bl=arry.remove(0);
System.out.println("取出商品,商品的型号:"+bl.name);
arry.notify();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
产品
package 消费者;
public class Bnanel {
public String name;
public Bnanel(String name){
this.name=name;
}
}主函数
package 消费者;
import java.util.ArrayList;
public class text {
public static void main(String[] args) {
ArrayList<Bnanel> arry=new ArrayList<Bnanel>();
Producter pd=new Producter(arry);
Consumer cm=new Consumer(arry);
pd.start();
cm.start();
}
}最后的运行结果为:
生产出香蕉型号为:香蕉的序号:1
生产出香蕉型号为:香蕉的序号:2
生产出香蕉型号为:香蕉的序号:3
生产出香蕉型号为:香蕉的序号:4
生产出香蕉型号为:香蕉的序号:5
。。。。。。
三、线程的生命周期
线程的生命周期主要分为五个主要的部分,即新建、就绪、阻塞、运行、死亡。新建就是线程建立一个实例对象;就绪就是线程已经启动但等待CPU调用;阻塞就是由于主观或客观的原因,线程停止运行;运行就是线程获得CPU资源并且正在执行任务即run方法;死亡就是当线程执行完毕或由于其他原因不能运行就叫作线程的死亡。
相关文章推荐
- Leetcode题解 347. Top K Frequent Elements
- 数据结构之—图
- NYOJ-+-字符串
- Vim基本操作
- 按照指定长度切割字符串
- HDOJ--5053--the Sum of Cube
- 学习笔记- AVFoundation Programming Guide - Using Assets
- 剑指offer——数组中重复的数字
- ScrollView 里嵌套WebView,WebView不能上下滑动或卡顿
- 使用MongoDB.NET 2.2.4驱动版本对 Mongodb3.3数据库中GridFS增删改查
- std::max
- 利用win7操作系统粘滞键漏洞更改Windows管理员密码
- Jenkins + Xcode + Fir.im 自动构建项目,并打包ipa上传(MAC)
- PreferenceScreen修改背景颜色
- Leetcode题解 268. Missing Number
- AngularJS
- 一些Editor整理(为自己)
- hdoj4548美素数
- 电商平台如何接入智选物流平台?
- atlas管理命令介绍