- 浏览: 1091867 次
文章分类
- 全部博客 (379)
- S2SH (16)
- stuts2 (0)
- java语言 (81)
- JSP (17)
- <html>元素 (11)
- javaweb (4)
- web容器 (3)
- ext (23)
- javaScript (48)
- ant (1)
- liferay (1)
- sql (9)
- css (42)
- 浏览器设置 (3)
- office_world (1)
- eclipse (4)
- 其它 (28)
- 操作系统 (5)
- android (6)
- Struts2 (11)
- RegEx (3)
- mysql (5)
- BigDATA (1)
- Node.js (1)
- Algorithm (10)
- Apache Spark (1)
- 数据库 (5)
- linux (2)
- git (1)
- Adobe (3)
- java语言,WebSocket (1)
- Maven (3)
- SHELL (1)
- XML (2)
- 数学 (2)
- Python (2)
- Java_mysql (1)
- ReactJS (6)
- 养生 (4)
- Docker (1)
- Protocols (3)
- java8 (2)
- 书籍 (1)
- Gradle (2)
- AngularJS (5)
- SpringMVC (2)
- SOAP (1)
- BootstrapCSS (1)
- HTTP协议 (1)
- OAuth2 (1)
最新评论
-
Lixh1986:
Java并发编程:自己动手写一把可重入锁https://blo ...
Java之多线程之Lock与Condition -
Lixh1986:
http://win.51apps.com.cn/https: ...
temp -
ztwsl:
不错,支持很好
HttpServletRequest和ServletRequest的区别 -
guodongkai:
谢谢您能将知识精华汇编总结,让初学者们从原理中学会和提高。
javaScript之function定义 -
kangwen23:
谢谢了,顶顶
struts2中的ValueStack学习
Java之多线程之Lock
接上文
在多线程环境中,大部分情况下,使用 synchronized 关键字可以满足需求。
但是其也存在不足。于是 java.util.concurrent.locks 包出现了。
第一篇
背景
在Java中实现线程同步的传统方法是使用synchronized关键字。
虽然它提供了一定的基本同步,但synchronized参数在使用时非常死板。
例如,一个线程只能锁一次。 同步块不提供等待队列的任何机制,
并且在一个线程退出后,任何线程都可以获取锁定。
这可能导致很长一段时间内某些其他线程的资源匮乏。
Java 从 1.5 开始,提供了可重入锁,以提供更大的灵活性同步。
一、概念
可重入锁
ReentrantLock
当某一线程在已经获取到该锁时,可再多次请求获取该锁,而该线程不会被阻塞而造成死锁。
它在线程不知是否已经获取到锁资源的情况下使用,非常有用。
相反,如果一个锁是不可重入的,当你已经获取到该锁资源,然后再次尝试获取该锁资源时,
就会自己把自己给锁住,造成线程死锁,一直阻塞在那里。
说明一:实现了Lock接口的类,都是可重入的。
可重入锁是 java.util.concurrent.locks.Lock 接口的实现之一。
另一个实现是 ReentrantReadWriteLock。
说明二:锁线程的方法介绍
- lock(), 拿不到lock就不罢休,不然线程就一直block。 比较无赖的做法。
- tryLock(),马上返回,拿到lock就返回true,不然返回false。 比较潇洒的做法。
- 带时间限制的tryLock(),拿不到lock,就等一段时间,超时返回false。比较聪明的做法。
- tryInterruptibly:在锁上等待,直到获取锁,但是会响应中断,
这个方法优先考虑响应中断,而不是响应锁的普通获取或重入获取。
二、代码示例
第二篇
一、Lock API 的主要类介绍
1、Lock 接口 - 实现类 ReentrantLock
接口类。规定了Lock的基本方法,这些方法可以满足所有 synchronized 的功能,
还提供了更多功能:Lock条件判断、Lock超时判断。
其最主要的方法:
lock():获取锁
unlock():释放锁
tryLock():等待锁一段时间再锁
newCondition():根据条件进行锁
1.1 Condition
背景知识:
- wait()、notify()
在多线程进行协同工作时,需要用到 wait()、notify() 。
wait()、notify() 只能用在 synchronized 块内部,而且是,synchronized 哪个对象,就得调用哪个对象的 wait()、notify() 方法。
Condition 类与Object类的 wait()、notify() 方法功能差不多。
但是提供了更多:可以创建不同的 wait 集合。
Condition 的实例必须由 Lock 类创建,而不是自己去 new 而产生。
主要方法:
await():类似于 Object.wait()
signal():类似于 Object.notify()
signalAll():类似于 Object.notifyAll()
1.2 ReentrantLock
该类被使用的最为广泛。它是在功能上实现了 synchronized 的类。
除了实现了从 Lock 接口继承的方法,它还自己有一些方法:
比如让线程等待一段时间再去获取资源的锁。
什么是 reentrant (可重入)?
其实 synchronized 代码块原本就是可重入(reentrant)的:
例如:
某线程正在执行 synchronized 代码块一,代码块一中需要执行代码块二,
两个代码块锁定的是同一个资源,此时线程一可以顺利执行此两个代码块。
无需重复获取资源的锁,即:资源锁重用。
看下面的例子:
线程在执行 foo()时,需要执行 bar(),此时直接执行即可,无需重复获取锁。
因为这两个 synchronized 代码块锁定的是同一个对象:this
2、ReadWriteLock 接口 - 实现类 ReentrantReadWriteLock
该类包含了一对相互关联的锁。
一种是:只读锁(Read-Only)。如果没有其它线程在占有写锁,该锁可以被多个线程同时拥有。
一种是:写锁。如果没有线程在占有读锁或写锁,该锁只能被一个线程独占。
二、Lock 使用示例
1、先看看用 synchronized 的写法:
2、使用 java.util.concurrent.locks.Lock 的写法:
3、ReentrantReadWriteLock
4. ReentrantReadWriteLock 使用Lock 实现缓存。
5. 双condition实现的阻塞式消息队列。
6. 使用 3 个 condition,使每个子线程各自交替执行。
7. Semaphore
Semaphore可以控制某个资源可被同时访问的个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。
比如在Windows下可以设置共享文件的最大客户端访问个数。
java.util.concurrent包之Execuotor系列文章
00_Java之 java.util.concurrent 包之概述
01_Java之java.util.concurrent包之Executor与ExecutorService
02_Java之 java.util.concurrent 包之ExecutorService之submit () 之 Future
03_Java之多线程之Callable与Future
04_Java之多线程之Lock
-
转载请注明,
原文出处:http://lixh1986.iteye.com/blog/2351294
引用:
http://www.journaldev.com/2377/java-lock-example-reentrantlock
接上文
在多线程环境中,大部分情况下,使用 synchronized 关键字可以满足需求。
但是其也存在不足。于是 java.util.concurrent.locks 包出现了。
第一篇
背景
在Java中实现线程同步的传统方法是使用synchronized关键字。
虽然它提供了一定的基本同步,但synchronized参数在使用时非常死板。
例如,一个线程只能锁一次。 同步块不提供等待队列的任何机制,
并且在一个线程退出后,任何线程都可以获取锁定。
这可能导致很长一段时间内某些其他线程的资源匮乏。
Java 从 1.5 开始,提供了可重入锁,以提供更大的灵活性同步。
一、概念
可重入锁
ReentrantLock
当某一线程在已经获取到该锁时,可再多次请求获取该锁,而该线程不会被阻塞而造成死锁。
它在线程不知是否已经获取到锁资源的情况下使用,非常有用。
相反,如果一个锁是不可重入的,当你已经获取到该锁资源,然后再次尝试获取该锁资源时,
就会自己把自己给锁住,造成线程死锁,一直阻塞在那里。
说明一:实现了Lock接口的类,都是可重入的。
可重入锁是 java.util.concurrent.locks.Lock 接口的实现之一。
另一个实现是 ReentrantReadWriteLock。
说明二:锁线程的方法介绍
- lock(), 拿不到lock就不罢休,不然线程就一直block。 比较无赖的做法。
- tryLock(),马上返回,拿到lock就返回true,不然返回false。 比较潇洒的做法。
- 带时间限制的tryLock(),拿不到lock,就等一段时间,超时返回false。比较聪明的做法。
- tryInterruptibly:在锁上等待,直到获取锁,但是会响应中断,
这个方法优先考虑响应中断,而不是响应锁的普通获取或重入获取。
二、代码示例
//Java code to illustrate Reentrant Locks import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.locks.ReentrantLock; class worker implements Runnable { SimpleDateFormat ft = new SimpleDateFormat("hh:mm:ss"); String jobName; ReentrantLock re; public worker(ReentrantLock rl, String n) { re = rl; jobName = n; } public void run() { boolean done = false; while (!done) { // Get lock - for the first time (outer lock) boolean ans = re.tryLock(); // Returns True if lock is free if (ans) { try { log("task %s - outer lock acquired at %s, Doing outer work - 1.5 s, lockHoldCount: %d", jobName, ft.format(new Date()), re.getHoldCount()); Thread.sleep(1500); // re lock - for the second time (inner lock) // This can happens in other method of other classes. re.lock(); try { log("task %s - inner lock acquired at %s, Doing inner work - 1.5 s, lockHoldCount: %d", jobName, ft.format(new Date()), re.getHoldCount()); Thread.sleep(1500); } catch (InterruptedException e) { e.printStackTrace(); } finally { // Inner lock release re.unlock(); log("task %s - releasing inner lock, lockHoldCount: %d", jobName, re.getHoldCount()); } log("task %s - work done", jobName); done = true; } catch (InterruptedException e) { e.printStackTrace(); } finally { // Outer lock release re.unlock(); log("task %s - releasing outer lock, lockHoldCount: %d", jobName, re.getHoldCount()); } } else { log("task %s - waiting for lock - 1 s", jobName); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } private void log(String pattern, Object... args) { System.out.println(String.format(pattern, args)); } } public class ReentrantLockTest { static final int MAX_T = 4; public static void main(String[] args) { ReentrantLock rel = new ReentrantLock(); ExecutorService pool = Executors.newFixedThreadPool(MAX_T); Runnable w1 = new worker(rel, "Job1"); Runnable w2 = new worker(rel, "Job2"); Runnable w3 = new worker(rel, "Job3"); Runnable w4 = new worker(rel, "Job4"); pool.execute(w1); pool.execute(w2); pool.execute(w3); pool.execute(w4); pool.shutdown(); } } /* output: task Job2 - waiting for lock - 1 s task Job4 - waiting for lock - 1 s task Job1 - outer lock acquired at 10:53:27, Doing outer work - 1.5 s, lockHoldCount: 1 task Job3 - waiting for lock - 1 s task Job4 - waiting for lock - 1 s task Job2 - waiting for lock - 1 s task Job3 - waiting for lock - 1 s task Job1 - inner lock acquired at 10:53:29, Doing inner work - 1.5 s, lockHoldCount: 2 task Job3 - waiting for lock - 1 s task Job4 - waiting for lock - 1 s task Job2 - waiting for lock - 1 s task Job1 - releasing inner lock, lockHoldCount: 1 task Job1 - work done task Job1 - releasing outer lock, lockHoldCount: 0 task Job3 - waiting for lock - 1 s task Job4 - waiting for lock - 1 s task Job2 - outer lock acquired at 10:53:31, Doing outer work - 1.5 s, lockHoldCount: 1 task Job4 - waiting for lock - 1 s task Job3 - waiting for lock - 1 s task Job2 - inner lock acquired at 10:53:32, Doing inner work - 1.5 s, lockHoldCount: 2 task Job4 - waiting for lock - 1 s task Job3 - waiting for lock - 1 s task Job2 - releasing inner lock, lockHoldCount: 1 task Job2 - work done task Job2 - releasing outer lock, lockHoldCount: 0 task Job3 - waiting for lock - 1 s task Job4 - outer lock acquired at 10:53:34, Doing outer work - 1.5 s, lockHoldCount: 1 task Job3 - waiting for lock - 1 s task Job4 - inner lock acquired at 10:53:35, Doing inner work - 1.5 s, lockHoldCount: 2 task Job3 - waiting for lock - 1 s task Job4 - releasing inner lock, lockHoldCount: 1 task Job4 - work done task Job4 - releasing outer lock, lockHoldCount: 0 task Job3 - outer lock acquired at 10:53:37, Doing outer work - 1.5 s, lockHoldCount: 1 task Job3 - inner lock acquired at 10:53:38, Doing inner work - 1.5 s, lockHoldCount: 2 task Job3 - releasing inner lock, lockHoldCount: 1 task Job3 - work done task Job3 - releasing outer lock, lockHoldCount: 0 */
第二篇
一、Lock API 的主要类介绍
1、Lock 接口 - 实现类 ReentrantLock
接口类。规定了Lock的基本方法,这些方法可以满足所有 synchronized 的功能,
还提供了更多功能:Lock条件判断、Lock超时判断。
其最主要的方法:
lock():获取锁
unlock():释放锁
tryLock():等待锁一段时间再锁
newCondition():根据条件进行锁
1.1 Condition
背景知识:
- wait()、notify()
在多线程进行协同工作时,需要用到 wait()、notify() 。
wait()、notify() 只能用在 synchronized 块内部,而且是,synchronized 哪个对象,就得调用哪个对象的 wait()、notify() 方法。
Condition 类与Object类的 wait()、notify() 方法功能差不多。
但是提供了更多:可以创建不同的 wait 集合。
Condition 的实例必须由 Lock 类创建,而不是自己去 new 而产生。
主要方法:
await():类似于 Object.wait()
signal():类似于 Object.notify()
signalAll():类似于 Object.notifyAll()
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.junit.Test; // 方法一: // 使用 wait 和 notify 控制线程, // 使子线程和主线程各交替执行一次。 //===================================================================== class UseWaitNotify { private Object dummy = new Object(); private boolean flag = true; public void subThread() { synchronized (dummy){ while(!flag){ try { dummy.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("[UseWaitNotify] sub.."); flag = false; dummy.notify(); } } public void mainThread(){ synchronized (dummy){ while(flag){ try { dummy.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("[UseWaitNotify] main.."); flag = true; dummy.notify(); } } } // test method class WaitNotify{ @Test public void testUseWaitNotify(){ UseWaitNotify useWaitNotify = new UseWaitNotify(); new Thread(new Runnable(){ @Override public void run() { for(int i = 0 ; i< 10; i++){ useWaitNotify.subThread(); } } }).start(); for(int i = 0 ; i< 10; i++){ useWaitNotify.mainThread(); } } } //方法二: //使用 await 和 signal 控制线程, //使子线程和主线程各交替执行一次。 //===================================================================== class UseCondition { private Lock lock = new ReentrantLock(); private Condition condition = lock.newCondition(); private boolean flag = true; public void subThread(){ lock.lock(); try{ while(!flag){ try { condition.await(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("[UseCondition] sub.."); flag = false; condition.signal(); }finally{ lock.unlock(); } } public void mainThread(){ lock.lock(); try{ while(flag){ try { condition.await(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("[UseCondition] main.."); flag = true; condition.signal(); }finally{ lock.unlock(); } } } //test method public class LockCondition { @Test public void testUseCondition(){ UseCondition useCondition = new UseCondition(); new Thread(new Runnable(){ @Override public void run() { for(int i = 0 ; i< 10; i++){ useCondition.subThread(); } } }).start(); for(int i = 0 ; i< 10; i++){ useCondition.mainThread(); } } }
1.2 ReentrantLock
该类被使用的最为广泛。它是在功能上实现了 synchronized 的类。
除了实现了从 Lock 接口继承的方法,它还自己有一些方法:
比如让线程等待一段时间再去获取资源的锁。
什么是 reentrant (可重入)?
其实 synchronized 代码块原本就是可重入(reentrant)的:
例如:
某线程正在执行 synchronized 代码块一,代码块一中需要执行代码块二,
两个代码块锁定的是同一个资源,此时线程一可以顺利执行此两个代码块。
无需重复获取资源的锁,即:资源锁重用。
看下面的例子:
public class Test{ public synchronized foo(){ //do something bar(); } public synchronized bar(){ //do some more } }
线程在执行 foo()时,需要执行 bar(),此时直接执行即可,无需重复获取锁。
因为这两个 synchronized 代码块锁定的是同一个对象:this
2、ReadWriteLock 接口 - 实现类 ReentrantReadWriteLock
该类包含了一对相互关联的锁。
一种是:只读锁(Read-Only)。如果没有其它线程在占有写锁,该锁可以被多个线程同时拥有。
一种是:写锁。如果没有线程在占有读锁或写锁,该锁只能被一个线程独占。
二、Lock 使用示例
1、先看看用 synchronized 的写法:
public class Resource { private Object dummy = new Object(); public void doSomething(){ synchronized(dummy){ System.out.println("do something..."); } } public void doLogging(){ System.out.println("do logging..."); } }
2、使用 java.util.concurrent.locks.Lock 的写法:
public class LockResource { private Lock lock; public LockResource(){ this.lock = new ReentrantLock(); } public void doSomething(){ try { if(lock.tryLock(10, TimeUnit.SECONDS)){ //时间单位:秒 System.out.println("do something.."); } } catch (InterruptedException e) { e.printStackTrace(); } finally{ lock.unlock(); // release the lock. } } public void doLogging(){ System.out.println("do logging..."); } }
3、ReentrantReadWriteLock
class Queue3{ private Object data = null; ReadWriteLock lock = new ReentrantReadWriteLock(); /* Read lock: - make sure no thread is writing. */ public void get(){ lock.readLock().lock(); System.out.println("read data..." + data); lock.readLock().unlock(); } /* Write lock: - make sure no thread is writing. - make sure no thread is reading. */ public void set(Object data){ lock.writeLock().lock(); System.out.println("write data..."); this.data = data; lock.writeLock().unlock(); } }
4. ReentrantReadWriteLock 使用Lock 实现缓存。
class CachedData { Object data; volatile boolean cacheValid; final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); void processCachedData() { rwl.readLock().lock(); if (!cacheValid) { // Must release read lock before acquiring write lock rwl.readLock().unlock(); rwl.writeLock().lock(); try { // Recheck state because another thread might have // acquired write lock and changed state before we did. if (!cacheValid) { data = ... cacheValid = true; } // Downgrade by acquiring read lock before releasing write lock rwl.readLock().lock(); } finally { rwl.writeLock().unlock(); // Unlock write, still hold read } } try { use(data); } finally { rwl.readLock().unlock(); } } }
5. 双condition实现的阻塞式消息队列。
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * 双condition实现的阻塞式消息队列。 * - 队列满时,不存 * - 队列空时,不取 */ public class LockConditionBlockingQueue { final Lock lock = new ReentrantLock(); final Condition notFull = lock.newCondition(); //控制存操作 final Condition notEmpty = lock.newCondition();//控制取操作 final Object[] items = new Object[100]; int putptr, takeptr, count; public void put(Object x) throws InterruptedException { lock.lock(); try { while (count == items.length) notFull.await(); items[putptr] = x; if (++putptr == items.length) putptr = 0; ++count; notEmpty.signal(); } finally { lock.unlock(); } } public Object take() throws InterruptedException { lock.lock(); try { while (count == 0) notEmpty.await(); Object x = items[takeptr]; if (++takeptr == items.length) takeptr = 0; --count; notFull.signal(); return x; } finally { lock.unlock(); } } }
6. 使用 3 个 condition,使每个子线程各自交替执行。
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.junit.Test; public class LockConditionThree { final int maxLoop = 100; @Test public void testUseCondition(){ UseCondition useCondition = new UseCondition(); new Thread(new Runnable(){ @Override public void run() { for(int i = 0 ; i< maxLoop; i++){ useCondition.sub1(); } } }).start(); new Thread(new Runnable(){ @Override public void run() { for(int i = 0 ; i< maxLoop; i++){ useCondition.sub2(); } } }).start(); new Thread(new Runnable(){ @Override public void run() { for(int i = 0 ; i< maxLoop; i++){ useCondition.sub3(); } } }).start(); } //使用 3 个 condition,使每个子线程各自交替执行。 //======================================================= static class UseCondition { private Lock lock = new ReentrantLock(); private Condition condition1 = lock.newCondition(); private Condition condition2 = lock.newCondition(); private Condition condition3 = lock.newCondition(); private int shouldSub = 1; public void sub1(){ lock.lock(); try{ while(shouldSub != 1){ try { condition1.await(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("sub1.."); shouldSub = 2; condition2.signal(); //notify thread 2 }finally{ lock.unlock(); } } public void sub2(){ lock.lock(); try{ while(shouldSub != 2){ try { condition2.await(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("sub2.."); shouldSub = 3; condition3.signal(); //notify thread 3 }finally{ lock.unlock(); } } public void sub3(){ lock.lock(); try{ while(shouldSub != 3){ try { condition3.await(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("sub3..\n"); shouldSub = 1; condition1.signal(); //notify thread 1 }finally{ lock.unlock(); } } } }
7. Semaphore
Semaphore可以控制某个资源可被同时访问的个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。
比如在Windows下可以设置共享文件的最大客户端访问个数。
import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; import java.util.concurrent.Semaphore; public class LockSemephore { public static void main(String[] args) { ExecutorService exec = Executors.newCachedThreadPool(); final Semaphore semp = new Semaphore(5); // 同时只能5个线程使用 for (int index = 0; index < 20; index++) { // 模拟20个客户端访问 final int NO = index; exec.execute(new Runnable() { public void run() { try { semp.acquire();// 获取许可 System.out.println("Accessing: " + NO); Thread.sleep(2000); semp.release();// 访问完后,释放 System.out.println("AvailablePermits:---------" + semp.availablePermits()); } catch (InterruptedException e) { e.printStackTrace(); } } }); } // 退出线程池 exec.shutdown(); System.out.println("done!"); } }
java.util.concurrent包之Execuotor系列文章
00_Java之 java.util.concurrent 包之概述
01_Java之java.util.concurrent包之Executor与ExecutorService
02_Java之 java.util.concurrent 包之ExecutorService之submit () 之 Future
03_Java之多线程之Callable与Future
04_Java之多线程之Lock
-
转载请注明,
原文出处:http://lixh1986.iteye.com/blog/2351294
引用:
http://www.journaldev.com/2377/java-lock-example-reentrantlock
评论
1 楼
Lixh1986
2018-11-13
Java并发编程:自己动手写一把可重入锁
https://blog.csdn.net/zhang5476499/article/details/83794711
https://blog.csdn.net/zhang5476499/article/details/83794711
发表评论
-
java 将文件夹所有的文件合并到指定的文件夹下
2020-06-30 19:17 979场景:将文件夹所有的文件合并到指定的文件夹下 另外:如果想效 ... -
多线程-线程池的四种创建方式
2020-04-01 18:38 414多线程-线程池的四种创建方式 https://blog.cs ... -
Java基础之:nio
2019-11-13 15:38 416一、理论讲解: 史上最强Java NIO入门:担心从入门到放弃 ... -
Java 分布式之:RPC 基本概念
2019-11-13 15:07 402转载: https://www.jianshu.com/p/ ... -
Java之 volatile 关键字原理详解
2019-11-07 15:36 445一、什么是 volatile ? ... -
POI实现excell批注背景图片(仿html浮窗显示图片)
2019-10-21 08:17 604POI实现excell批注背景图片(仿html浮窗显示图片) ... -
Java之设计模式之 Observer 观察者
2019-07-04 17:21 974观察者设计模式 Java 已经实现了该模式,并且提供了使用类 ... -
HashMap, LinkedHashMap and TreeMap
2019-03-01 11:04 628https://stackoverflow.com/a/177 ... -
Java lib 操作 excel 插入图片
2019-01-19 12:46 839https://poi.apache.org/componen ... -
数据库连接池C3P0
2018-05-29 16:50 814一、名字的由来 很多 ... -
Java8之集合(Collection)遍历 forEach()、stream()
2018-05-29 14:39 20663package java8.collections; ... -
Junit Vs main on "java.util.concurrent.Executors"
2017-11-10 16:44 734Same code with different result ... -
Java之大数据学习路线
2017-11-03 10:08 5674三个月大数据研发学习 ... -
Java中创建对象的5种方式
2017-10-26 14:21 809一、Java之5种创建对象的方式 ————————————— ... -
Log4j和Slf4j的比较
2017-06-23 12:41 1365一直搞不清 Log4j 和 SLF4j 的关系。今天才若有所 ... -
Java之Java7新特性之try资源句式
2017-04-20 14:58 5341Java之Java7新特性之try资源句式 一、【try资源 ... -
Java之 java.util.concurrent 包之ExecutorService之submit () 之 Future
2017-03-04 21:27 3774一、如何使用 ExecutorService.submit() ... -
Java之 java.util.concurrent 包之Executor与ExecutorService
2017-03-04 21:18 2647一、问题: execute() 与 submit() 的区别? ... -
JAVAEE之单用户登录
2017-02-05 11:55 1032单用户登录是系统中数据一直性的解决方案之一。 问题背景: 试 ... -
Java之多线程之线程池之线程重复使用
2017-02-04 13:33 5523一、问题背景 在使用多线程时,如果要开启一个任务,则就需要新 ...
相关推荐
主要介绍了Java多线程中ReentrantLock与Condition详解,需要的朋友可以参考下
java多线程实现生产者和消费者 ,4种实现方式,分别为synchronizated,condition和lock,信号量,阻塞队列
在char01包里放置Java多线程基本知识的代码。内容如下: 如何使用多线程 如何得到多线程的一些信息 如何停止线程 如何暂停线程 线程的一些其他用法 在char02包里放置了Java对变量和对象并发访问的知识的代码...
java 并发 编程 多线程 concurrent lock condition executorserice executor java.util.curcurrent.
Java多线程入阶干货分享 1.使用线程的经验:设置名称、响应中断、使用ThreadLocal 2.Executor:ExecutorService和Future 3.阻塞队列:put和take、offer和poll、drainTo 4.线程间通信:lock、condition、wait、notify...
本书全面解析了Java并发编程的核心概念、原理和实践,帮助读者深入理解多线程并发编程的精髓,提升编程能力和系统性能。 书中首先介绍了并发编程的基础知识,包括线程的基本概念、线程的生命周期、线程安全等问题。...
【2018最新最详细】并发多线程教程,课程结构如下 1.并发编程的优缺点 2.线程的状态转换以及基本操作 3.java内存模型以及happens-before规则 4.彻底理解synchronized 5.彻底理解volatile 6.你以为你真的了解final吗...
JUC(Java Util Concurrent)是Java中用于并发编程的工具包,提供了一组接口和类,用于处理多线程和并发操作。JUC提供了一些常用的并发编程模式和工具,如线程池、并发集合、原子操作等。 JUC的主要特点包括: ...
在学习Java过程中,自己收集了很多的Java的学习资料,分享给大家,有需要的欢迎下载,希望对大家有用,一起学习,一起进步。
Lock锁,一种线程同步机制,其主要功能是防止多个线程同时访问同一代码块,从而避免因并发问题引发的数据不一致或其他错误。...总的来说,Lock锁是Java多线程编程中的重要工具,能够有效保障程序运行的正确性和稳定性。
了解多线程所带来的安全风险.mp4 从线程的优先级看饥饿问题.mp4 从Java字节码的角度看线程安全性问题.mp4 synchronized保证线程安全的原理(理论层面).mp4 synchronized保证线程安全的原理(jvm层面).mp4 单例问题...
如果你是一名Java开发人员,并且想进一步掌握并发编程和多线程技术,并挖掘Java 7并发的新特性,那么本书是你的合适之选。 《Java 7并发编程实战手册》 第1章 线程管理 1 1.1 简介 1 1.2 线程的创建和运行...
Lock 接口概述: 简要介绍 Lock 接口,解释其在多线程编程中的作用和优势。比较 Lock 接口与传统 synchronized 关键字的不同之处。 常用 Lock 接口实现类: 详细讲解 Lock 接口的一些常用实现类,如 ReentrantLock、...
采用同步机制synchronized/wait(notify)或者lock(unlock)/condition variable实现两个producer和一个consumer之间协调运行。运行结果输出格式为:Put(or Get) number {[content] length start_index end_index} 包含...
第2节理解多线程与并发的之间的联系与区别 [免费观看] 00:11:59分钟 | 第3节解析多线程与多进程的联系以及上下文切换所导致资源浪费问题 [免费观看] 00:13:03分钟 | 第4节学习并发的四个阶段并推荐学习并发的资料 ...
第2节理解多线程与并发的之间的联系与区别 [免费观看] 00:11:59分钟 | 第3节解析多线程与多进程的联系以及上下文切换所导致资源浪费问题 [免费观看] 00:13:03分钟 | 第4节学习并发的四个阶段并推荐学习并发的资料 ...
7 一个支持多线程的服务器框架 13. 8 代理服务器 13. 9 Telnet客户端 13. 10 UDP编程 13. 11 聊天室服务器端 13. 12 聊天室客户端 13. 13 FTP客户端 第14章 数据库 14. 1 连接各种...
第2节理解多线程与并发的之间的联系与区别 [免费观看] 00:11:59分钟 | 第3节解析多线程与多进程的联系以及上下文切换所导致资源浪费问题 [免费观看] 00:13:03分钟 | 第4节学习并发的四个阶段并推荐学习并发的资料 ...
《Linux多线程服务端编程:使用muduo C++网络库》主要讲述采用现代C++在x86-64 Linux上编写多线程TCP网络服务程序的主流常规技术,重点讲解一种适应性较强的多线程服务器的编程模型,即one loop per thread。...