java并发编程——共享资源的操作
2015-07-18 11:40
543 查看
一、并发编程产生的问题
并发编程给程序的设计带来的巨大的好处,但多线程的出现也同样带来了一些问题。
因为线程执行的时间是不确定的,所以,当不同的线程共同访问某一共享资源的时候,可以对共享资源的操作产生错误。
比如:有一共享资源整型num,如果有几个线程同时对其做减1操作。假设当num=90时,线程一对其做减一操作,其从内存中取出num=90,然后到cpu进行减法操作。
这个时候,线程一挂起,线程二开始执行,线程二从内存中取出num=90,对其进行减一操作,num变为了89,。而线程切换到线程一的时候,线程一继续执行,在cpu中做减法操作,num变为89。
也就是执行了两次减一操作,当时共享资源num只是从90变为了89.
二、如何解决这一问题——互斥量操作
1、为了保护资源,采用了加锁的方式。当资源被一个任务使用的时候,对其进行加锁操作。只用当前任务完成,才释放锁。下一个任务才能访问该资源。
在java中使用synchronized关键字的形式控制资源的访问。
2、共享资源。在java中共享资源一般是以对象的形式存在内存片段的。但也可以是文件,输入输出端口,或者是打印机。
3、synchronized的使用
(1)将方法标记为synchronized,如果某个任务处于一个标记为synchroenized的方法的调用中,那么在这个线程从该方法返回之前,其他所有要调用类中任何标记为synchronized方法的线程都会被阻塞。
(2)临界区
有时,希望防止多个线程同时访问方法内部的部分代码,而不是防止访问整个方法。
通过这种方法,分离出来的代码段称为临界区,它使用synchronized关键字建立。
synchronized被用来指定某个对象,此对象的锁被用来对花括号内的代码进行同步控制。
synchronized(对象)
{
需要控制的代码!
}
这种方法叫做同步控制块,通过同步控制块,而不是对整个方法进行同步控制,可以使得多个任务访问对象的时间性能得到显著提高。
使用一对象,作为锁
并发编程给程序的设计带来的巨大的好处,但多线程的出现也同样带来了一些问题。
因为线程执行的时间是不确定的,所以,当不同的线程共同访问某一共享资源的时候,可以对共享资源的操作产生错误。
比如:有一共享资源整型num,如果有几个线程同时对其做减1操作。假设当num=90时,线程一对其做减一操作,其从内存中取出num=90,然后到cpu进行减法操作。
这个时候,线程一挂起,线程二开始执行,线程二从内存中取出num=90,对其进行减一操作,num变为了89,。而线程切换到线程一的时候,线程一继续执行,在cpu中做减法操作,num变为89。
也就是执行了两次减一操作,当时共享资源num只是从90变为了89.
二、如何解决这一问题——互斥量操作
1、为了保护资源,采用了加锁的方式。当资源被一个任务使用的时候,对其进行加锁操作。只用当前任务完成,才释放锁。下一个任务才能访问该资源。
在java中使用synchronized关键字的形式控制资源的访问。
2、共享资源。在java中共享资源一般是以对象的形式存在内存片段的。但也可以是文件,输入输出端口,或者是打印机。
3、synchronized的使用
(1)将方法标记为synchronized,如果某个任务处于一个标记为synchroenized的方法的调用中,那么在这个线程从该方法返回之前,其他所有要调用类中任何标记为synchronized方法的线程都会被阻塞。
(2)临界区
有时,希望防止多个线程同时访问方法内部的部分代码,而不是防止访问整个方法。
通过这种方法,分离出来的代码段称为临界区,它使用synchronized关键字建立。
synchronized被用来指定某个对象,此对象的锁被用来对花括号内的代码进行同步控制。
synchronized(对象)
{
需要控制的代码!
}
这种方法叫做同步控制块,通过同步控制块,而不是对整个方法进行同步控制,可以使得多个任务访问对象的时间性能得到显著提高。
使用一对象,作为锁
package com.xiancheng; class task1 implements Runnable { private int num = 100; Object o = new Object(); public void run() { while(num>0) { synchronized(o) { if(num>0) { try { Thread.sleep(10); } catch(InterruptedException e) { } System.out.println(Thread.currentThread().getName()+"........"+num--); } } } } } class task2 implements Runnable { private int num = 100; // Object o = new Object(); public void run() { while(num>0) { synchronized(this) { if(num>0) { try { Thread.sleep(10); } catch(InterruptedException e) { } System.out.println(Thread.currentThread().getName()+"........"+num--); } } } } } class task2 implements Runnable { public void run() { for(int z=0;z<=10;z++) { for(int y=0;y<=99999999;y++){} System.out.println(Thread.currentThread().getName()+"....z="+z); } } } public class hello { public static void main(String[] args){ task1 t1= new task1(); task2 t2 = new task2(); Thread nt1 = new Thread(t1); Thread nt2 = new Thread(t1); Thread nt3 = new Thread(t1); nt1.start(); nt2.start(); nt3.start(); } }
相关文章推荐
- java新手笔记3 运算符&循环
- struts2 JSON 插件的使用
- java.util.ResourceBundle的用法及报错
- Head First Java资源
- Java Web框架
- 【并发编程】JMM:java内存模型抽象
- 7月18日Java基础:本人为新手正在学习Java中把每天学的东西晚上都会在博客记录希望大神可以指点 不足在此谢过。
- Java中native关键字
- java.sql.SQLException: Could not retrieve transation read-only status server
- [LeetCode][Java] Subsets
- JavaStuNote 4
- Struts2核心(4)——登录问题
- 从[java.lang.OutOfMemoryError: Java heap space]恢复
- [转] 解决windows下eclipse中android项目关联android library project失败问题
- java中数组的初始化和基本排序算法
- Java数据库连接(JDBC)之一:JDBC详细连接过程
- Eclipse和MyEclipse的区别
- java自定义注解
- java自定义注解
- Eclipse和MyEclipse的区别 分类: 编程工具 2015-07-18 11:12 23人阅读 评论(0) 收藏