- 浏览: 715539 次
文章分类
最新评论
-
白天看黑夜:
Apache Mina Server 2.0 中文参考手册(带 ...
基于Mina的Http Server以及简单的Http请求客户端 -
Baple:
...
Maven常用配置 -
喵喵大神:
推荐聚合数据上一些免费API接口https://www.juh ...
又一波开放API接口 精品文摘、站内搜索、笑话详情 -
ioandy:
请问楼主,为什么我在测试的时候,会收到2次请求?
基于Mina的Http Server以及简单的Http请求客户端 -
jammk:
之前看到一个,应该也是灵图的,http://www.cnblo ...
又来一只开放API——基于FAQ的问答机器人
1.synchronized关键字
synchronized是用来控制线程的并发执行的,它只能作用于一个方法或者一个代码块上,通过它能保证一段代码或一个方法有多个线程调用时能顺序执行。
工作机制:
当程序运行到非静态的synchronized同步方法上时,自动获得与正在执行代码类的当前实例(this实例)有关的锁。获得一个对象的锁也称为获取锁、锁定对象、在对象上锁定或在对象上同步。
当程序运行到synchronized同步方法或代码块时才该对象锁才起作用。一个对象只有一个锁。所以,如果一个线程获得该锁,就没有其他线程可以获得锁,直到第一个线程释放(或返回)锁。这也意味着任何其他线程都不能进入该对象上的synchronized方法或代码块,直到该锁被释放。释放锁是指持锁线程退出了synchronized同步方法或代码块。
示例代码:
使用synchronized锁,可能造成死锁的问题。最典型的是线程1先锁A,再来锁B,线程2先锁B,再来锁A,如下代码:
2.wait,notify,notifyAll
任意Java对象都有如下3个方法,不同线程之间可以利用同一个对象的这三个方法进行通信。
关于等待/通知,要记住的关键点是:
必须从同步环境内(就是synchronized 代码块内)调用wait()、notify()、notifyAll()方法。线程不能调用对象上等待或通知的方法,除非它拥有那个对象的锁。
void notify()
唤醒在此对象监视器上等待的单个线程。 有重载的。
void notifyAll()
唤醒在此对象监视器上等待的所有线程。
void wait()
导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。
最经典的例子就是生产者,消费者的例子。
代码如下,百度来的
本例仅仅是生产者消费者模型中最简单的一种表示,本例中,如果消费者消费的仓储量达不到满足,而又没有生产者,则程序会一直处于等待状态,这当然是不对的。实际上可以将此例进行修改,修改为,根据消费驱动生产,同时生产兼顾仓库,如果仓不满就生产,并对每次最大消费量做个限制,这样就不存在此问题了,当然这样的例子更复杂,更难以说明这样一个简单模型。
synchronized是用来控制线程的并发执行的,它只能作用于一个方法或者一个代码块上,通过它能保证一段代码或一个方法有多个线程调用时能顺序执行。
工作机制:
当程序运行到非静态的synchronized同步方法上时,自动获得与正在执行代码类的当前实例(this实例)有关的锁。获得一个对象的锁也称为获取锁、锁定对象、在对象上锁定或在对象上同步。
当程序运行到synchronized同步方法或代码块时才该对象锁才起作用。一个对象只有一个锁。所以,如果一个线程获得该锁,就没有其他线程可以获得锁,直到第一个线程释放(或返回)锁。这也意味着任何其他线程都不能进入该对象上的synchronized方法或代码块,直到该锁被释放。释放锁是指持锁线程退出了synchronized同步方法或代码块。
示例代码:
package com.ajita; public class TestSynchronized { class Account { private int total = 0; public synchronized void add(int n) { total = total + n; } public synchronized void minus(int n) { total = total - n; } public int getTotal() { return total; } } class AddThread extends Thread { private Account acct; private int addCount = 0; AddThread(String name, Account acct, int addNum) { super(name); this.acct = acct; this.addCount = addNum; } public void run() { for (int i = 0; i < addCount; i++) { acct.add(1); System.out.println(this.getName() + acct.getTotal()); try { Thread.sleep(11); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } class MinusThread extends Thread { private Account acct; private int minusNum = 0; MinusThread(String name, Account acct, int minusNum) { super(name); this.acct = acct; this.minusNum = minusNum; } public void run() { for (int i = 0; i < minusNum; i++) { acct.minus(1); System.out.println(this.getName() + acct.getTotal()); try { Thread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } public void test() { Account a = new Account(); System.out.println(a.getTotal()); Thread addThread = new AddThread("add", a, 50); Thread minusThread = new MinusThread("minus", a, 50); addThread.start(); minusThread.start(); try { addThread.join(); minusThread.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(a.getTotal()); } /** * @param args */ public static void main(String[] args) { TestSynchronized test = new TestSynchronized(); test.test(); } }
使用synchronized锁,可能造成死锁的问题。最典型的是线程1先锁A,再来锁B,线程2先锁B,再来锁A,如下代码:
package com.ajita; public class TestDeadLock { public class DeadlockRisk { private Object resourceA = new Object(); private Object resourceB = new Object(); public void lockAFirst() { synchronized (resourceA) { try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } synchronized (resourceB) { System.out.println("lockAFirst get Locked"); } } } public void lockBFirst() { synchronized (resourceB) { try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } synchronized (resourceA) { System.out.println("lockBFirst get Locked"); } } } } class LockAFirstThread extends Thread { public DeadlockRisk deadLock; public void run() { deadLock.lockAFirst(); } } class LockBFirstThread extends Thread { public DeadlockRisk deadLock; public void run() { deadLock.lockBFirst(); } } public void test() { DeadlockRisk lock = new DeadlockRisk(); LockAFirstThread a = new LockAFirstThread(); a.deadLock = lock; LockBFirstThread b = new LockBFirstThread(); b.deadLock = lock; a.start(); b.start(); } /** * @param args */ public static void main(String[] args) { TestDeadLock test = new TestDeadLock(); test.test(); } }
2.wait,notify,notifyAll
任意Java对象都有如下3个方法,不同线程之间可以利用同一个对象的这三个方法进行通信。
关于等待/通知,要记住的关键点是:
必须从同步环境内(就是synchronized 代码块内)调用wait()、notify()、notifyAll()方法。线程不能调用对象上等待或通知的方法,除非它拥有那个对象的锁。
void notify()
唤醒在此对象监视器上等待的单个线程。 有重载的。
void notifyAll()
唤醒在此对象监视器上等待的所有线程。
void wait()
导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。
最经典的例子就是生产者,消费者的例子。
代码如下,百度来的
package com.ajita; /** * Java线程:并发协作-生产者消费者模型 * * @author leizhimin 2009-11-4 14:54:36 */ public class ProducerAndConsumer { public static void main(String[] args) { Godown godown = new Godown(30); Consumer c1 = new Consumer(50, godown); Consumer c2 = new Consumer(20, godown); Consumer c3 = new Consumer(30, godown); Producer p1 = new Producer(10, godown); Producer p2 = new Producer(10, godown); Producer p3 = new Producer(10, godown); Producer p4 = new Producer(10, godown); Producer p5 = new Producer(10, godown); Producer p6 = new Producer(10, godown); Producer p7 = new Producer(80, godown); c1.start(); c2.start(); c3.start(); p1.start(); p2.start(); p3.start(); p4.start(); p5.start(); p6.start(); p7.start(); } } /** * 仓库 */ class Godown { public static final int max_size = 100; // 最大库存量 public int curnum; // 当前库存量 Godown() { } Godown(int curnum) { this.curnum = curnum; } /** * 生产指定数量的产品 * * @param neednum */ public synchronized void produce(int neednum) { // 测试是否需要生产 while (neednum + curnum > max_size) { System.out.println("要生产的产品数量" + neednum + "超过剩余库存量" + (max_size - curnum) + ",暂时不能执行生产任务!"); try { // 当前的生产线程等待 wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // 满足生产条件,则进行生产,这里简单的更改当前库存量 curnum += neednum; System.out.println("已经生产了" + neednum + "个产品,现仓储量为" + curnum); // 唤醒在此对象监视器上等待的所有线程 notifyAll(); } /** * 消费指定数量的产品 * * @param neednum */ public synchronized void consume(int neednum) { // 测试是否可消费 while (curnum < neednum) { try { // 当前的生产线程等待 wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // 满足消费条件,则进行消费,这里简单的更改当前库存量 curnum -= neednum; System.out.println("已经消费了" + neednum + "个产品,现仓储量为" + curnum); // 唤醒在此对象监视器上等待的所有线程 notifyAll(); } } /** * 生产者 */ class Producer extends Thread { private int neednum; // 生产产品的数量 private Godown godown; // 仓库 Producer(int neednum, Godown godown) { this.neednum = neednum; this.godown = godown; } public void run() { // 生产指定数量的产品 godown.produce(neednum); } } /** * 消费者 */ class Consumer extends Thread { private int neednum; // 生产产品的数量 private Godown godown; // 仓库 Consumer(int neednum, Godown godown) { this.neednum = neednum; this.godown = godown; } public void run() { // 消费指定数量的产品 godown.consume(neednum); } }
本例仅仅是生产者消费者模型中最简单的一种表示,本例中,如果消费者消费的仓储量达不到满足,而又没有生产者,则程序会一直处于等待状态,这当然是不对的。实际上可以将此例进行修改,修改为,根据消费驱动生产,同时生产兼顾仓库,如果仓不满就生产,并对每次最大消费量做个限制,这样就不存在此问题了,当然这样的例子更复杂,更难以说明这样一个简单模型。
发表评论
-
JVM常用参数设置
2013-12-04 15:24 1957堆内存设置示例:java -Xmx3550m -Xms35 ... -
Java垃圾回收机制
2013-04-02 17:03 1189Java的垃圾 ... -
JVM(SUN)设置【转】
2013-04-02 16:10 1043堆大小设置JVM 中最 ... -
Java与字符编码
2012-09-26 18:20 2844Java支持很多字符编(这是一句废话,各种语言都支持很多字符编 ... -
Java nio
2012-03-16 14:18 1438本文转载自http://www.iteye.com/topic ... -
Java API实现HTTP Server
2012-03-16 13:38 8095JDK6提供了一个简单的Http Server API ... -
Java基本数据结构
2012-03-09 23:04 927本文转载自:http://blog.sina.com.cn/s ... -
Java锁
2012-03-09 22:50 2680说明:Java多线程相关相关几篇文章转自http://lava ... -
Java有返回值的线程
2012-03-09 22:42 1349Java中可返回值的任务(线程)必须实现Callabl ... -
Java线程池
2012-03-09 22:33 17731.Java提供了若干的原生线程池,一般都能满足我们的需要。 ... -
Java线程调度
2012-03-07 00:11 1343Java线程调度是Java多线程的核心,只有良好的调度 ... -
Java多线程启动方式
2012-03-04 23:09 81971.Java新建线程的方式: ...
相关推荐
Java synchronized同步锁可以保证同一时刻只有一个线程操作同一资源,使用wait()、notify()切换线程状态保证线程操作的前后顺序实现线程交互。 Java线程状态有五种:新建状态、就绪状态、运行状态、休眠状态和死亡...
标题和描述概述的知识点主要集中在Java的多线程机制中,特别是`wait`和`notify`方法在同步锁中的应用。这些方法对于控制线程之间的交互至关重要,尤其是在资源有限或需要确保数据一致性的情况下。 ### Java同步锁...
Java提供了多种线程同步机制,如synchronized关键字、wait()和notify()方法、ReentrantLock等。 在给定的文件中,我们有以下几个文件: 1. **Producer.java**:这个文件可能包含一个生产者线程的实现,它的任务是...
在“操作系统实验 多线程同步与互斥 java编写 有界面”的实验中,可能需要设计一个图形用户界面(GUI),通过按钮或事件触发线程的创建和同步操作,直观地展示线程间的交互和同步效果。例如,可以模拟银行账户转账,...
Java中,可以通过wait()、notify()和notifyAll()这三个Object类的方法来实现线程间的通信。这些方法必须在同步环境中使用,否则会抛出异常。此外,Java 5引入了BlockingQueue阻塞队列,它是一种线程安全的数据结构,...
在Java中,`wait()`、`notify()`和`notifyAll()`方法都是与对象锁相关的,它们用于控制线程的同步。使用这些方法的前提是线程必须拥有对象的监视器,也就是对象锁。这是通过在synchronized块或方法中调用它们来实现...
`wait()`和`notify()`/`notifyAll()`方法用于线程间的通信,使得线程可以在特定条件下释放资源并等待其他线程唤醒;`ReentrantLock`可重入锁提供了更灵活的控制,支持公平锁和非公平锁策略。 线程优先级是调度的...
5. **线程间通信**:除了锁机制,JVM还提供了一系列的线程间通信工具,如`ThreadLocal`、`Wait/Notify`、`CountDownLatch`、`Semaphore`、`CyclicBarrier`等,用于解决线程间的同步问题,使多线程程序更加灵活和可控...
为了在多线程中同步进度更新,我们可以利用synchronized关键字、wait()、notify()方法,或者使用Java并发库中的高级工具,如Semaphore、CyclicBarrier或CountDownLatch等。 一个简单的进度条实现可以采用共享变量...
3. **线程同步与并发控制**:论文会深入讲解JAVA中的线程同步机制,如synchronized关键字、wait()、notify()和notifyAll()方法,以及Lock接口和ReentrantLock类的使用。此外,可能会探讨并发工具类,如Semaphore、...
`wait()`和`notify()`是对象级别的锁控制,用于线程间的通信,一个线程调用`wait()`会释放当前持有的锁并等待,而其他线程调用`notify()`或`notifyAll()`可以唤醒等待的线程。 "BounceThread"这个示例可能涉及到...
在synchronized方法或代码块内部,可以通过调用wait()方法使当前线程放弃锁,并进入等待状态,直到其他线程调用notify()方法或notifyAll()方法。notify()方法唤醒在此对象监视器上等待的单个线程,而notifyAll()方法...
- 线程间的交互涉及到线程间的数据传递和同步操作,主要技术包括 `wait()`、`notify()`、`notifyAll()` 等方法,以及 `CountDownLatch`、`CyclicBarrier` 等类。 #### 七、Java线程:线程的调度 1. **休眠** - `...
Java 中的线程可以通过多种方式进行交互,如 wait() 和 notify() 方法、join() 方法、LockSupport 类等。wait() 方法可以用于线程等待某个条件的满足,而 notify() 方法可以用于通知其他线程某个条件的满足。join() ...
在Java中,线程的协同主要通过`wait()`和`notify()`或`notifyAll()`方法来实现,这些方法定义在`Object`类中。当一个线程调用`wait()`时,它会释放当前持有的锁并进入等待状态,直到其他线程调用`notify()`或`...
在Java中,线程间通信是通过共享内存(变量)和同步机制(如synchronized关键字、wait/notify机制)来实现的。例如,如果这个示例是银行转账操作,那么两个线程分别代表不同的账户,它们需要在修改余额时进行同步,...
线程同步主要包括synchronized关键字、wait/notify机制、Lock锁(如ReentrantLock)以及Semaphore信号量等,它们用于避免竞态条件,确保共享资源的安全访问。 接着,我们来看Java内存模型(JMM),这是理解多线程...