线程互斥是一次只有一个线程执行某段代码,保证数据的一致性。线程通信是指通过notify或notifyAll来唤醒在wait某个对象锁的线程。实现方式是通过synchronized关键字声明。
1. 如果同步代码块在对象方法中,可以实例化一个Object来作为lock的对象,或者用this关键字表示lock这个对象:
synchronized(obj) {
// code block
}
synchronized(this) {
// code block
}
2. 如果同步代码块在静态方法中,使用一个静态对象,如当前class的字节码来作为lock的对象:
synchronized(CurrentClass.class) {
// code block
}
3. synchronized修饰整个方法,这时锁的对象就是当前实例化的对象,保证一次只有一个线程执行这个方法:
public synchronized void warranty() {
// code segment
}
public synchronized void merchantability() {
// code segment
}
如果对象的两个或两个以上方法都加了synchronized修饰符,则一次只能由一个线程执行其中的某一个方法。
我们可以把需要互斥执行的代码分别放到这些方法里实现互斥,然后辅以wait和notify实现通信,看下面的例子:
主线程执行100次A代码后,由辅线程执行10次B代码,然后再由主线程执行100次A代码,辅线程10次B代码,如此循环40次。
public class TraditionalConcurrentCommunication {
public static void main(String[] args) {
// Ensure to operate the same object
final Cooperation cooperation = new Cooperation();
// Main thread
new Thread(new Runnable() {
@Override
public void run() {
for (int t = 1; t <= 40; t++) {
try {
cooperation.first(t);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
// Sub thread
new Thread(new Runnable() {
@Override
public void run() {
for (int t = 1; t <= 40; t++) {
try {
cooperation.second(t);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
static class Cooperation {
private boolean bFirst = true;
public synchronized void first(int times) throws InterruptedException {
while (!bFirst) { // 使用状态标志防止伪唤醒
wait(); // 在当前对象上等待被唤醒
}
for (int i = 1; i <= 100; i++) {
System.out.println(Thread.currentThread().getName() + " is executing first() in loop of " + i
+ " of the " + times + " times");
}
bFirst = false;
notify(); // 通知在当前对象上等待的线程,即Sub thread
}
public void second(int times) throws InterruptedException {
while (bFirst) {
wait();
}
for (int i = 1; i <= 10; i++) {
System.out.println(Thread.currentThread().getName() + " is executing second() in loop of " + i
+ " of the " + times + " times");
}
bFirst = true;
notify(); // 通知在当前对象上等待的线程,即Main thread
}
}
}
这里把业务逻辑放到一个类的两个方法中,体现了面向对象的编程思想。
分享到:
相关推荐
title: 3-1-案例-售票&线程状态- Java多线程基础- Java多线程案例categories: Java多线程基础售票案例线程状态售票的动作需要被
java.util.concurrent-多线程框架
Java-concurrent-collections-concurrenthashmap-blockingqueue.pdf
//d2这个线程开启,多了一条执行路径//由主线程执行// * 主线程出异常会导致其所在线程结束但是不会影响其他线程的执行// * Exception in t
非守护线程创建的线程默认为非守护线程,守护则默认为守护线程优先级(priority)优先级高的线程可以得到更多cpu资源, 级别是1-10,默认优先级和创建他的
JavaEE源代码 concurrent-1.3.2JavaEE源代码 concurrent-1.3.2JavaEE源代码 concurrent-1.3.2JavaEE源代码 concurrent-1.3.2JavaEE源代码 concurrent-1.3.2JavaEE源代码 concurrent-1.3.2JavaEE源代码 concurrent-...
Java concurrentMap 内存模型深入分析 HotCode
backport-util-concurrent.jarbackport-util-concurrent.jarbackport-util-concurrent.jar
官方版本,亲测可用
concurrent-all-in-one.pdf
Beginning with an introduction of the topic, this text describes the concurrency model of Java, summarizing its strengths and weaknesses, as well as details the Real-Time Specification for Java.
io.github.hank.java.concurrent.n2 - 同步与异步 io.github.hank.java.concurrent.n3 - Java线程 io.github.hank.java.concurrent.n4 - 共享模型之管程 io.github.hank.java.concurrent.n5 - 共享模型之内存 io....
This book provides an introduction to concurrent, real-time, distributed programming with Java object-oriented language support as an algorithm description tool. It describes in particular the ...
concurrent-1.3.4-sources.jar
- copy %AXIS2_HOME%\lib\backport-util-concurrent-3.1.jar 到%ECLIPSE_HOME%\plugins\Axis2_Codegen_Wizard_1.3.0\lib - 注册此 jar 包: 編輯 %ECLIPSE_HOME%\plugins\Axis2_Codegen_Wizard_1.3.0\plugin.xml , ...
backport-util-concurrent-3.1.jar 和 geronimo-stax-api_1.0_spec-1.0.1.jar 复制到 MyEclipse 6.5\eclipse\plugins\Axis2_Codegen_Wizard_1.3.0\lib 文件夹下。 (3).注册此 jar 包: 修改MyEclipse 6.5\eclipse...
java concurrent 阻塞队列 线程 里面有详细的例子,下载后请认真阅读里面的内容,可能有点难以理解,请耐心
Concurrent-Utils Utilities for Java concurrent library. This is a library contains some useful and smart utility class for Java concurrent library. Shelly, HermesEventBus and AndroidDataStorage are ...
在Eclipse3.5用Axis2中创建wsdl文件时,在最后一步出现如下错误: An error ocCurred while ...解决用到的jar包,两个jar包在backport-util-concurrent-3.1.jar和geronimo-stax-api_1.0_spec-1.0.1.jar.zip的压缩文件中
* Thread类中的run方法内部的任务并不是我们所需要的,既然thread类已经定义了线程任务的位置只要重写run方法定义任务的代码即可.* 多线程执行时,