synchronized
package com.yuzhenc.thread;
public class Test12 {
public static void main(String[] args) {
Product p = new Product();
ProducerThread producerThread = new ProducerThread(p);
CustomerThread customerThread = new CustomerThread(p);
producerThread.start();
customerThread.start();
}
}
class Product {
private String brand;
private String name;
boolean flag = false;
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public synchronized void setProduct(String brand, String name) {
if(flag == true) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.setBrand(brand);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.setName(name);
System.out.println("生产者生产了:" + this.getBrand() + "---" + this.getName());
flag = true;
notify();
}
public synchronized void getProduct(){
if(!flag){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("消费者消费了:" + this.getBrand() + "---" + this.getName());
flag = false;
notify();
}
}
class ProducerThread extends Thread{
private Product p;
public ProducerThread(Product p) {
this.p = p;
}
@Override
public void run() {
for (int i = 1; i <= 10 ; i++) {
if(i % 2 == 0){
p.setProduct("费列罗","巧克力");
}else{
p.setProduct("哈尔滨","啤酒");
}
}
}
}
class CustomerThread extends Thread {
private Product p;
public CustomerThread(Product p) {
this.p = p;
}
@Override
public void run() {
for (int i = 1; i <= 10 ; i++) {
p.getProduct();;
}
}
}
Lock
- Condition是在Java 1.5中才出现的,它用来替代传统的Object的wait()、notify()实现线程间的协作,相比使用Object的wait()、notify(),使用Condition1的await()、signal()这种方式实现线程间协作更加安全和高效
- 在Object的监视器模型上,一个对象拥有一个同步队列和等待队列,而Lock(同步器)拥有一个同步队列和多个等待队列
- Object中的wait(),notify(),notifyAll()方法是和"同步锁"(synchronized关键字)捆绑使用的;而Condition是需要与"互斥锁"/"共享锁"捆绑使用的\
- 调用Condition的await()、signal()、signalAll()方法,都必须在lock保护之内,就是说必须在lock.lock()和lock.unlock之间才可以使用
- void await() throws InterruptedException
- 造成当前线程在接到信号或被中断之前一直处于等待状态,与此 Condition 相关的锁以原子方式释放,并且出于线程调度的目的,将禁用当前线程,且在发生以下四种情况之一 以前,当前线程将一直处于休眠状态
- 其他某个线程调用此 Condition 的 signal() 方法,并且碰巧将当前线程选为被唤醒的线程
- 其他某个线程调用此 Condition 的 signalAll() 方法
- 其他某个线程中断当前线程,且支持中断线程的挂起
- 发生“虚假唤醒”
- void signal()
- 唤醒一个等待线程,如果所有的线程都在等待此条件,则选择其中的一个唤醒。在从 await 返回之前,该线程必须重新获取锁
- void signalAll()
- 唤醒所有等待线程,如果所有的线程都在等待此条件,则唤醒所有线程。在从 await 返回之前,每个线程都必须重新获取锁
package com.yuzhenc.thread;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Test12 {
public static void main(String[] args) {
Product p = new Product();
ProducerThread producerThread = new ProducerThread(p);
CustomerThread customerThread = new CustomerThread(p);
producerThread.start();
customerThread.start();
}
}
class Product {
private String brand;
private String name;
Lock lock = new ReentrantLock();
Condition produceCondition = lock.newCondition();
Condition consumeCondition = lock.newCondition();
boolean flag = false;
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setProduct(String brand,String name){
lock.lock();
try{
if(flag == true){
try {
produceCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.setBrand(brand);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.setName(name);
System.out.println("生产者生产了:" + this.getBrand() + "---" + this.getName());
flag = true;
consumeCondition.signal();
}finally {
lock.unlock();
}
}
public void getProduct(){
lock.lock();
try{
if(!flag){
try {
consumeCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("消费者消费了:" + this.getBrand() + "---" + this.getName());
flag = false;
produceCondition.signal();
}finally {
lock.unlock();
}
}
}
class ProducerThread extends Thread{
private Product p;
public ProducerThread(Product p) {
this.p = p;
}
@Override
public void run() {
for (int i = 1; i <= 10 ; i++) {
if(i % 2 == 0){
p.setProduct("费列罗","巧克力");
}else{
p.setProduct("哈尔滨","啤酒");
}
}
}
}
class CustomerThread extends Thread {
private Product p;
public CustomerThread(Product p) {
this.p = p;
}
@Override
public void run() {
for (int i = 1; i <= 10 ; i++) {
p.getProduct();;
}
}
}
|