`

Java多线程之Lock的使用 .

 
阅读更多
01.import java.util.concurrent.ExecutorService;  
02.import java.util.concurrent.Executors;  
03.import java.util.concurrent.Future;  
04.import java.util.concurrent.locks.Lock;  
05.import java.util.concurrent.locks.ReadWriteLock;  
06.import java.util.concurrent.locks.ReentrantLock;  
07.import java.util.concurrent.locks.ReentrantReadWriteLock;  
08.  
09./** 
10. * Lockers 
11. * 在多线程编程里面一个重要的概念是锁定,如果一个资源是多个线程共享的,为了保证数据的完整性, 
12. * 在进行事务性操作时需要将共享资源锁定,这样可以保证在做事务性操作时只有一个线程能对资源进行操作, 
13. * 从而保证数据的完整性。在5.0以前,锁定的功能是由Synchronized关键字来实现的。 
14. */  
15.public class Lockers {  
16.      
17.    /** 
18.     * 测试Lock的使用。在方法中使用Lock,可以避免使用Synchronized关键字。 
19.     */  
20.    public static class LockTest {  
21.  
22.        Lock lock = new ReentrantLock();// 锁   
23.        double value = 0d; // 值   
24.        int addtimes = 0;  
25.  
26.        /** 
27.         * 增加value的值,该方法的操作分为2步,而且相互依赖,必须实现在一个事务中 
28.         * 所以该方法必须同步,以前的做法是在方法声明中使用Synchronized关键字。 
29.         */  
30.        public void addValue(double v) {  
31.            lock.lock();// 取得锁   
32.            System.out.println("LockTest to addValue: " + v + "   "  
33.                    + System.currentTimeMillis());  
34.            try {  
35.                Thread.sleep(1000);  
36.            } catch (InterruptedException e) {  
37.            }  
38.            this.value += v;  
39.            this.addtimes++;  
40.            lock.unlock();// 释放锁   
41.        }  
42.  
43.        public double getValue() {  
44.            return this.value;  
45.        }  
46.    }  
47.    public static void testLockTest() throws Exception{  
48.        final LockTest lockTest = new LockTest();  
49.        // 新建任务1,调用lockTest的addValue方法   
50.        Runnable task1 = new Runnable(){  
51.            public void run(){  
52.                lockTest.addValue(55.55);  
53.            }  
54.        };  
55.        // 新建任务2,调用lockTest的getValue方法   
56.        Runnable task2 = new Runnable(){  
57.            public void run(){  
58.                System.out.println("value: " + lockTest.getValue());  
59.            }  
60.        };  
61.        // 新建任务执行服务   
62.        ExecutorService cachedService = Executors.newCachedThreadPool();  
63.        Future future = null;  
64.        // 同时执行任务1三次,由于addValue方法使用了锁机制,所以,实质上会顺序执行   
65.        for (int i=0; i<3; i++){  
66.            future = cachedService.submit(task1);  
67.        }  
68.        // 等待最后一个任务1被执行完   
69.        future.get();  
70.        // 再执行任务2,输出结果   
71.        future = cachedService.submit(task2);  
72.        // 等待任务2执行完后,关闭任务执行服务   
73.        future.get();  
74.        cachedService.shutdownNow();  
75.    }  
76.      
77.    /** 
78.     * ReadWriteLock内置两个Lock,一个是读的Lock,一个是写的Lock。 
79.     * 多个线程可同时得到读的Lock,但只有一个线程能得到写的Lock, 
80.     * 而且写的Lock被锁定后,任何线程都不能得到Lock。ReadWriteLock提供的方法有: 
81.     * readLock(): 返回一个读的lock  
82.     * writeLock(): 返回一个写的lock, 此lock是排他的。 
83.     * ReadWriteLockTest很适合处理类似文件的读写操作。 
84.     * 读的时候可以同时读,但不能写;写的时候既不能同时写也不能读。 
85.     */  
86.    public static class ReadWriteLockTest{  
87.        // 锁   
88.        ReadWriteLock lock = new ReentrantReadWriteLock();  
89.        // 值   
90.        double value = 0d;  
91.        int addtimes = 0;  
92.          
93.        /** 
94.         * 增加value的值,不允许多个线程同时进入该方法 
95.         */  
96.        public void addValue(double v) {  
97.            // 得到writeLock并锁定   
98.            Lock writeLock = lock.writeLock();  
99.            writeLock.lock();  
100.            System.out.println("ReadWriteLockTest to addValue: " + v + "   "  
101.                    + System.currentTimeMillis());  
102.            try {  
103.                Thread.sleep(1000);  
104.            } catch (InterruptedException e) {  
105.            }  
106.            try {  
107.                // 做写的工作   
108.                this.value += v;  
109.                this.addtimes++;  
110.            } finally {  
111.                // 释放writeLock锁   
112.                writeLock.unlock();  
113.            }  
114.        }  
115.        /** 
116.         * 获得信息。当有线程在调用addValue方法时,getInfo得到的信息可能是不正确的。 
117.         * 所以,也必须保证该方法在被调用时,没有方法在调用addValue方法。 
118.         */  
119.        public String getInfo() {  
120.            // 得到readLock并锁定   
121.            Lock readLock = lock.readLock();  
122.            readLock.lock();  
123.            System.out.println("ReadWriteLockTest to getInfo   "  
124.                    + System.currentTimeMillis());  
125.            try {  
126.                Thread.sleep(1000);  
127.            } catch (InterruptedException e) {  
128.            }  
129.            try {  
130.                // 做读的工作   
131.                return this.value + " : " + this.addtimes;  
132.            } finally {  
133.                // 释放readLock   
134.                readLock.unlock();  
135.            }  
136.        }  
137.    }  
138.      
139.    public static void testReadWriteLockTest() throws Exception{  
140.        final ReadWriteLockTest readWriteLockTest = new ReadWriteLockTest();  
141.        // 新建任务1,调用lockTest的addValue方法   
142.        Runnable task_1 = new Runnable(){  
143.            public void run(){  
144.                readWriteLockTest.addValue(55.55);  
145.            }  
146.        };  
147.        // 新建任务2,调用lockTest的getValue方法   
148.        Runnable task_2 = new Runnable(){  
149.            public void run(){  
150.                System.out.println("info: " + readWriteLockTest.getInfo());  
151.            }  
152.        };  
153.        // 新建任务执行服务   
154.        ExecutorService cachedService_1 = Executors.newCachedThreadPool();  
155.        Future future_1 = null;  
156.        // 同时执行5个任务,其中前2个任务是task_1,后两个任务是task_2   
157.        for (int i=0; i<2; i++){  
158.            future_1 = cachedService_1.submit(task_1);  
159.        }  
160.        for (int i=0; i<2; i++){  
161.            future_1 = cachedService_1.submit(task_2);  
162.        }  
163.        // 最后一个任务是task_1   
164.        future_1 = cachedService_1.submit(task_1);  
165.        // 这5个任务的执行顺序应该是:   
166.        // 第一个task_1先执行,第二个task_1再执行;这是因为不能同时写,所以必须等。   
167.        // 然后2个task_2同时执行;这是因为在写的时候,就不能读,所以都等待写结束,   
168.        // 又因为可以同时读,所以它们同时执行   
169.        // 最后一个task_1再执行。这是因为在读的时候,也不能写,所以必须等待读结束后,才能写。   
170.          
171.        // 等待最后一个task_2被执行完   
172.        future_1.get();  
173.        cachedService_1.shutdownNow();  
174.    }  
175.  
176.    public static void main(String[] args) throws Exception{  
177.        Lockers.testLockTest();  
178.        System.out.println("---------------------");  
179.        Lockers.testReadWriteLockTest();  
180.    }  
181.}  
分享到:
评论

相关推荐

    Java多线程的经典资料.rar

    Java多线程是Java编程中的核心概念,它允许程序同时执行多个任务,极大地提升了软件的效率和并发性。这份“Java多线程的经典资料.rar”压缩包包含了一份名为“Java线程.pdf”的文档,很可能是关于Java多线程的详细...

    Java多线程编程核心技术.zip

    Java多线程编程是Java开发中的重要组成部分,它允许程序同时执行多个任务,提升系统效率。在Java中,实现多线程主要有两种方式:继承Thread类和实现Runnable接口。本资料"Java多线程编程核心技术.zip"深入探讨了这些...

    JAVA多线程编程技术探讨.pdf

    ### JAVA多线程编程技术探讨 #### 摘要与关键词 本文主要探讨了JAVA多线程编程技术的基础,特别是线程的创建方法、线程管理和线程同步处理技术。关键词包括:JAVA、多线程、创建、管理、同步。 #### 前言 在多线程...

    Java多线程编程核心技术_完整版_java_

    Java多线程编程是Java开发中的重要组成部分,它允许程序同时执行多个任务,极大地提高了程序的效率和响应性。在Java中,多线程主要通过继承Thread类或实现Runnable接口来实现。本教程《Java多线程编程核心技术》将...

    java多线程设计模式详解.rar

    Java多线程设计模式是Java开发中不可或缺的一部分,它涉及到并发编程的核心概念和技术。在Java中,多线程可以提高程序的执行效率,通过合理利用CPU资源,使得多个任务能够同时进行。本压缩包文件“java多线程设计...

    java多线程完整使用教程.rar

    本教程将全面介绍Java多线程的使用,帮助你掌握这个核心技能。 首先,理解线程的基本概念是必要的。线程是程序执行的最小单位,每个线程都有自己的程序计数器、寄存器和栈,它们共享同一块内存空间,即同一进程中的...

    Java多线程编程深入详解.docx

    Java多线程编程深入详解 多线程编程是Java编程语言中的一种重要技术,用于提高程序的执行效率和响应速度。在本文中,我们将深入探讨Java多线程编程的基础知识和高级技术。 什么是多进程和多线程? 在计算机科学中...

    Java多线程之-死锁.doc

    Java 多线程之死锁 Java 多线程中的死锁是指两个或两个以上的线程互相持有对方所需要的资源,由于 synchronized 的特性,一个线程持有一个资源,或者说获得一个锁,在该线程释放这个锁之前,其它线程是获取不到这个...

    java多线程龟兔赛跑程序.zip

    "java多线程龟兔赛跑程序.zip"是一个示例项目,它使用Java语言来实现经典的龟兔赛跑故事,以帮助开发者理解如何在多线程环境下进行编程。这个项目可能包含了源代码、测试文件以及其他相关文档,其主要目标是演示如何...

    Java多线程的临界资源.pdf

    "Java多线程的临界资源" Java 多线程的临界资源是指在多线程编程中,多个线程并发访问共享资源时可能出现的问题。这些问题往往是由于线程运行顺序的不确定引起的,是一种时序问题,是多线程所独有的问题。 在 Java...

    JAVA并发多线程的面试问题及答案-java多线程并发面试题.docx

    在这里,我们将从面试的角度列出了大部分重要的问题,但是你仍然应该牢固的掌握Java多线程基础知识来对应日后碰到的问题。 1. 多线程和并发问题 在 Java 中,多线程和并发问题是非常重要的。面试官通常会问一些...

    Java多线程同步问题分析.pdf

    Java多线程同步问题分析主要关注的是在并发环境中如何有效地管理共享资源,避免出现数据竞争和不一致性。在Java编程中,多线程是提升程序性能的重要手段,尤其是在服务器端应用和服务中。然而,当多个线程同时访问并...

    Java多线程的用法_.docx

    Java多线程是一种重要的编程概念...总之,Java多线程提供了强大的并发处理能力,但正确使用多线程需要对系统资源、任务特性以及线程安全有深入理解。在处理大量数据时,合理地划分任务和分配线程是提高程序效率的关键。

    java 多线程编程实战指南(核心 + 设计模式 完整版)

    《Java多线程编程实战指南》这本书深入浅出地讲解了Java多线程的核心概念和实战技巧,分为核心篇和设计模式篇,旨在帮助开发者掌握并应用多线程技术。 1. **线程基础** - **线程的创建**:Java提供了两种创建线程...

    java多线程进度条

    本主题将深入探讨如何在Java多线程环境下实现进度条功能。 首先,理解Java多线程的基本概念至关重要。Java通过Thread类和Runnable接口来支持多线程。创建一个新线程通常有两种方式:继承Thread类并重写run()方法,...

    基于Java多线程同步的安全性研究.pdf

    文章首先介绍了Java多线程同步的必要性和重要性,然后讨论了Java多线程同步机制的实现方法,包括使用synchronized关键字和Java.util.concurrent.locks包中的Lock对象。接着,文章讨论了Java多线程同步机制中可能出现...

    计算机Java多线程下载技术分析.zip

    总结,Java多线程下载技术涉及线程创建、并发执行、同步控制、I/O操作等多个方面,通过合理设计和优化,可以显著提高文件下载效率。实践中,开发者需要根据具体应用场景选择合适的策略,并充分考虑错误处理和用户...

    Java多线程[归类].pdf

    Java多线程编程是Java平台中的重要特性,它允许程序同时执行多个任务,从而提高CPU资源的利用率。在Java中,实现多线程有两种主要方式: 1. 继承Thread类:创建一个新的类,该类继承自Thread类,并重写run()方法。...

    JAVA多线程探讨 (2).pptx

    【JAVA多线程探讨】 Java多线程是Java编程中不可或缺的一部分,特别是在处理并发和分布式系统时。在Java中,多线程允许程序同时执行多个不同的任务,从而提高应用程序的效率和响应性。本篇文章将深入探讨Java多线程...

    JAVA多线程编程详解3.pdf

    Java多线程编程是Java开发中的重要组成部分,它允许程序同时执行多个任务,提升程序的效率和响应性。本文将详细解析Java中的多线程概念、实现方式以及相关的编程技巧。 首先,我们要理解多线程的基本概念。多线程是...

Global site tag (gtag.js) - Google Analytics