线程模型
一、同步模型
最常见的例子就是银行取款,A,B两个人分别在银行对一个账户进行取款操作,账户仅有1000余额,当同事点击取款1000的按钮时,银行会怎样处理呢?
每个人都查询到了余额1000元没错,即使同时取款,也会有一方不成功的,否则的话,银行会被搞垮的,他才没那么笨,但是这该如何实现呢?
1、synchronized同步关键字
这里涉及到多个线程对共享资源进行处理,这里就必须要给线程“排队”,使用的关键字是synchronized(同步),在程序中,给对共享资源进行处理的代码部分(整个方法或代码块)添加此关键字。相当于给代码块加锁,取得钥匙的线程对资源操作,完成后将钥匙交予其他线程,这保证了同一个资源某一时间内只有一个线程可以对其修改等操作。
public void func(){
//代码
synchronized(锁){
//对共享资源处理代码
}
//代码
}
这里注意:
(1)、锁本身必须是共享的资源,不能使局部变量,如在方法内部定义锁,然后使用的话,这样的代码是无意义的,每个对象都会实例化一个锁,锁就失去了作用。比如超市的储物柜钥匙如果每人一把的话,那谁还敢把东西放进去呢。
public void func(){
Object lock = new Object();
//代码
synchronized(lock){//锁失去了意义
//对共享资源处理代码
}
//代码
}
(2)、锁可以是任何一个类型即Object
(3)、注意细分锁。可以有多个锁对象,对不同的资源“上锁”
class A{
private Object lock1 = new Object();
private Object lock2 = new Object();
void f(){
synchronized(lock1){
//访问资源P
}
}
void g(){
synchronized(lock2){
//访问资源Q
}
}
}
2、Lock 锁对象
除了synchronized还可以用Lock创建临界区
class A{
Lock lock = new ReentrantLock();
void f(){
lock.lock();//加锁
try{
//访问资源
}finally{
lock.unlock();//解锁
}
}
]
3、synchronized 和 Lock
(1)Lock的锁定时通过代码实现的,synchronized是在JVM层面上实现的
(2)synchronized在锁定时如果出现方法块抛出异常,JVM会自动解锁,不会造成因为异常而死锁。
Lock在出现异常时只能在finally{}将锁释放。
(3)Lock能完成synchronized所实现的所有功能
(4)Lock有比synchronized更精确的线程语义和更好的性能。
(5)在资源竞争不是很激烈的情况下,synchronized的性能优于ReentrantLock,但是当资源竞争很激烈时,synchronized的性能会下降几十倍,而ReentrantLock的性能维持常态。
二、生产/消费模型
生产者生产一件产品放到仓库,消费者从仓库取走产品,生产者再生产一件...
有几种方式呢?
1、消费者不停的问“有货吗?有货吗?有货吗?”。这无疑是很浪费资源的方式
2、wait()/notify()
消费者处于wait(),生产者生产出产品则notify(),然后wait()消费者收到信息进行消费,然后notify生产者,并在此处于wait(),生产者再继续生产...
生产者类的代码;
/**
* 生产者线程:无数据时再存,存入一个就发通知
* @author Administrator
*
*/
public class ProduceThread extends Thread{
//用来标记放入对象的每一个独立ID号
private static int count = 0;
//与消费线程或共同存取的对象列表
private List shareList;
public ProduceThread(List shareList){
this.shareList = shareList;
}
public void run(){
System.out.println("生产线程已经启动 。。。"+shareList.size());
while(true){
try{
Thread.sleep(2000);
synchronized(shareList){
while(shareList.size()>0){
shareList.wait();//有货,等待
}
while(shareList.size()==0){//无货,生产
Student st = new Student();
count++;
st.id = count;
st.name = count+"aaa";
System.out.println("--->生产线程放入对象:"+st.toString());
shareList.add(st);
shareList.notify();//通知
}
}
}catch(Exception ef){
ef.printStackTrace();
}
}
}
}
消费者类的代码:
/**
* 取数据线程:当有数据时取,取完通知
* @author Administrator
*
*/
public class CustomerThread extends Thread{
private List shareList;
public CustomerThread(List shareList){
this.shareList = shareList;
}
public void run(){
System.out.println("消费线程已经启动。。。"+shareList.size());
while(true){
try{
synchronized(shareList){
while(shareList.size()==0){
//如果没有,消费线程则等待
shareList.wait();
}
while(shareList.size()>0){
System.out.println("<---消费线程取出 "+shareList.remove(0).toString());
//取了一个已经,立即发出通知
shareList.notify();
}
}
}catch(Exception ef){
ef.printStackTrace();
}
}
}
}
注意wait()和sleep()的区别是:
wait()释放锁等待,而sleep()是不释放锁的,即,它在休眠的时候仍然占用资源。
三、双缓冲模型
双缓冲模型有两个队列A,B,生产者将产品放到队列A中,消费者从队列B中拿产品,当B队列为空时,将A队列的产品存入B。当B不为空时,消费者只管取货,生产者只管生产,两者之间没有直接的联系,只有B为空时,将B队列同步起来,再将A同步起来,A中产品倒入B。
这样,就可以大大减少处理同步的次数。
如有不足,欢迎指正!
分享到:
相关推荐
Java线程模型的缺陷主要体现在其非面向对象的设计和对并发编程支持的不足。在Java中,线程通常被视为独立的run()方法执行实体,而非与对象紧密关联的组件。这种设计导致开发者在处理异步信息和同步控制时面临挑战。 ...
Java 编程语言的线程模型可能是此语言中最薄弱的部分。它完全不适合实际复杂程序的要求,而且也完全不是面向对象的。本文建议对 Java 语言进行重大修改和补充,以解决这些问题。 Java 语言的线程模型是此语言的一个...
7. Java线程模型的优化:本文的主要贡献在于,扩展了Java同步线程模型的语法,提高了Java线程模型的稳定性和可靠性。 8. Java开发者的参考:本文为Java开发者提供了有价值的参考,讨论了Java线程模型的缺陷和改进...
目前普遍采用急救包(Band-Aid)类库的方式解决Java 线程模型存在的同步问题,但类库中的代码很难或无法实 ...通过扩展语法方法解决了同步问题,以确保使用Java线程所开发的 程序的稳定、可靠和可优化。
Java线程模型是基于操作系统的原生线程模型构建的,这意味着每个Java线程通常映射到操作系统的一个线程。 1. **线程的创建与启动** - **通过`Thread`类创建**:直接继承自`Thread`类并重写其`run()`方法,然后创建...
Java自定义线程模型在软件开发中扮演着重要的角色,特别是在高性能、高并发的应用场景,如游戏服务器。本文将深入探讨如何在Java中构建自定义线程模型,并分享一些实践经验。 首先,我们要明白为什么要自定义线程...
Java线程具有创建、就绪、运行、阻塞和死亡五种状态。创建状态是指用new操作创建了一个Thread实例,但尚未调用start()方法;就绪状态是指线程可以运行,但CPU还未分配时间片;运行状态是指线程获得CPU时间片,正在...
Java线程模型主要包括以下几个方面: 1. **线程生命周期**:Java线程具有不同的生命周期状态,包括新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Terminated)等状态。 2. **线程优先级...
Java线程模型: * 线程是虚拟的CPU,由java.lang.Thread类封装和虚拟CPU来实现。 * CPU所执行的代码传递给Thread类对象,CPU所处理的数据传递给Thread类对象。 创建和启动Java线程: * 可以使用extends Thread...
Java线程模型是Java编程中一个非常重要的概念,它涉及到多任务处理和并发执行。在Java中,线程模型的设计和实现对程序的性能、可扩展性和资源利用有着深远的影响。"threadmodel"项目旨在深入解析Java中的BIO( ...
Java线程模型主要包括三个部分:线程体(Runnable接口或Thread类)、线程控制块(Thread对象)和虚拟机的线程调度器。线程体负责定义线程的行为,线程控制块用于存储线程的状态,而线程调度器则负责调度线程的执行。...
#### 二、Java线程模型 - **线程模型**:Java中的线程模型主要包括线程对象、线程状态、线程同步机制等。 - **线程对象**:通过`java.lang.Thread`类或实现`Runnable`接口创建线程。 - **线程状态**:Java线程有...
java多线程经典模型生产者消费者java多线程经典模型生产者消费者java多线程经典模型生产者消费者java多线程经典模型生产者消费者java多线程经典模型生产者消费者java多线程经典模型生产者消费者java多线程经典模型...
- **Java中的线程模型**:Java线程模型主要基于`Thread`类和`Runnable`接口。创建线程有两种基本方法:继承`Thread`类或实现`Runnable`接口。 #### 多线程在.NET里如何工作? 在.NET框架中,线程通过`System....
"Java同步线程模型分析与改进" Java同步线程模型是Java语言中的一种多线程机制,能够提高计算机资源的使用效率和处理速度。但是,Java多线程模型也存在一些缺陷,例如死锁问题等。因此,需要对Java同步线程模型进行...
Java线程-Java内存模型是Java并发编程中的关键概念,它描述了多个线程如何共享和访问内存资源,以及如何保证数据的一致性和安全性。Java内存模型(JMM)是Java虚拟机规范的一部分,用于定义程序中各个线程对共享变量...
本资源提供了 Java 编程详细教程中的 Java 线程部分的详细知识点,涵盖了多线程基本概念、Java 线程模型、创建线程、两种线程创建方式的比较、线程状态等内容,对 Java 编程的学习和研究具有非常重要的参考价值。
关于操作系统平台,Java线程模型和底层平台的线程模型有关,例如Windows和Linux使用不同的机制实现线程,但Java提供了统一的线程模型。在跨平台的Java程序中,开发者不需要关心底层线程模型的具体差异,可以专注于...