码迷,mamicode.com
首页 > 其他好文 > 详细

并发(二)

时间:2017-09-30 15:06:00      阅读:172      评论:0      收藏:0      [点我收藏+]

标签:dex   一个   fda   span   父类   jdb   调用   his   java编程   

本篇讲述一下多线程中,共享受限资源。

 参考文章:

http://blog.csdn.net/luoweifu/article/details/46613015

《Java编程思想》

1.不正确的访问资源

请看例子:

技术分享
 1 public class ThreadDemo02 implements Runnable{
 2 
 3     private static int i = 0;
 4     
 5     public void run() {
 6         //synchronized (this) {
 7             System.out.println(Thread.currentThread().getName() + " i value is " + i++);
 8         //}
 9     }
10 }
View Code
技术分享
 1 import java.util.concurrent.ExecutorService;
 2 import java.util.concurrent.Executors;
 3 import java.util.concurrent.TimeUnit;
 4 
 5 public class ThreadDemo03 {
 6 
 7     public static void main(String[] args) throws InterruptedException {
 8 
 9         ThreadDemo02 demo02 = new  ThreadDemo02();
10         ExecutorService service = Executors.newCachedThreadPool();
11         for (int i = 0; i < 10; i++) {
12             service.execute(demo02);
13         }
14         service.shutdown();
15     }
16 }
View Code

这是实际执行的结果:

技术分享
 1 pool-1-thread-2 i value is 0
 2 pool-1-thread-6 i value is 3
 3 pool-1-thread-3 i value is 1
 4 pool-1-thread-4 i value is 2
 5 pool-1-thread-1 i value is 0
 6 pool-1-thread-5 i value is 5
 7 pool-1-thread-7 i value is 4
 8 pool-1-thread-8 i value is 6
 9 pool-1-thread-3 i value is 7
10 pool-1-thread-8 i value is 8
View Code

而我期待的结果是下面这样的:

技术分享
 1 pool-1-thread-1 i value is 0
 2 pool-1-thread-6 i value is 1
 3 pool-1-thread-5 i value is 2
 4 pool-1-thread-7 i value is 3
 5 pool-1-thread-4 i value is 4
 6 pool-1-thread-3 i value is 5
 7 pool-1-thread-2 i value is 6
 8 pool-1-thread-8 i value is 7
 9 pool-1-thread-5 i value is 8
10 pool-1-thread-8 i value is 9
View Code

这是因为共享资源竞争造成的结果。

 

2.解决共享资源竞争

 2.1第一种方式是使用synchronized的方式。

在这里需要注意的是,synchronized锁的对象指的是同一对象内的。如果有两个对象,那么就会有两把锁,两把锁之间相互独立,没有影响。

在使用并发时,将域设置为private是非常重要的,否则,synchronized关键字就不能防止其他任务直接访问域,这样就会产生冲突。

syschronized是Java中的关键字,它修饰的对象有以下几种:

(1)修饰域,被称为同步代码块,作用的对象是调用这个方法的对象;

(2)修饰方法,作用的范围是整个方法,作用的对象是调用这个方法的对象;

(3)修饰静态方法,作用的对象是这个类的所有对象;

(4)修饰类,作用的对象是整个类的所有的对象。

 

 在用synchronized修饰方法时要注意以下几点:

(1)synchronized关键字不能被继承。虽然,可以使用synchronized来定义方法,但是synchronized并不属于方法定义的一部分,因此它不能被继承。如果在父类中的某个方法使用了synchronized关键字,而在子类中覆盖了这个方法,那么子类的这个方法默认情况下并不是同步的,而必须显示第在子类的这个方法中加上synchronized关键字。当然,还可以在子类中调用父类的方法,虽然子类中的方法不是同步的,但是子类调用了父类的同步方法,因此,子类的方法也就相当于是同步了。

(2)构造方法不能使用synchronized关键字,但是在方法内部可以使用synchronized代码块。

(3)下面使用synchronized的方式是等价的。

技术分享
1 public synchronized void method {
2     // to do
3 }
4 
5 public void method {
6     synchronized(this) {
7         
8     }
9 }
View Code

 

2.2使用显示的Lock对象

Lock对象必须被显式第创建、锁定、和释放,跟内建的锁形式相比,代码缺乏优雅性,但是更加灵活,赋予了你更加细粒度的控制力。这对于实现专用结构是很有用的,例如用于遍历链表中的节点的节节传递的加锁机制,这种遍历代码必须在释放当前节点的锁之前捕获下一个节点的锁。(红色部分观点摘自《Java 编程思想》)

这里我将JDBC的transaction联系起来,觉得这样大家会更好理解。

自己去设置上锁和解锁的时间点,跟事务开始结束的设置,我认为是一样的。

 

Lock的代码稍后补充,要去打篮球去。。。

并发(二)

标签:dex   一个   fda   span   父类   jdb   调用   his   java编程   

原文地址:http://www.cnblogs.com/lihao007/p/7614505.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!