sychonized:是为了多线程资源共享同步
ThreadLocal:是为了多线程资源独占式
1.生产消费者模型
我们最理想的模型是生产者和消费者的速度匹配。
2.通知的使用
在正式进入生产者和消费者模型之前我们先做一些准备基础。在生产者消费者里面最核心的就是通知和等待,下面我们将看看用什么样的方法可以是实现等待或者通知。
(1) 等待:wait()
其实wait()方法就是使线程停止运行。在同步代码块中使用。
(2) 通知:notify() :通知一个线程
notifyAll(): 通知所有线程
它们都在同步代码块中使用。
package com.wschase.shengchanzhexiaofeizhe;
import org.omg.PortableServer.THREAD_POLICY_ID;
/**
* Author:WSChase
* Created:2019/1/13
*/
public class TestNotifyAll {
public static void main(String[] args) {
Object object=new Object();
new Thread(new MyRunnable(true,object),"生产者A").start();
new Thread(new MyRunnable(true,object),"生产者B").start();
new Thread(new MyRunnable(true,object),"生产者C").start();
new Thread(new MyRunnable(false,object),"消费者A").start();
new Thread(new MyRunnable(false,object),"消费者B").start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class MyRunnable implements Runnable{
//如果是true表示生产者
//如果是false表示消费者
private final boolean flag;
private final Object object;
/**
*
* @param flag 表示生产者还是消费者
* @param object 表示资源(锁)
*/
MyRunnable(boolean flag,Object object) {
this.flag = flag;
this.object=object;
}
@Override
public void run() {
if(flag){
this.waitMethod();
}else{
this.notifyMethod();
}
}
//消费者通知
private void notifyMethod() {
synchronized (object){
String name=Thread.currentThread().getName();
System.out.println(name+"消费者开始");
this.object.notifyAll();//给所有等待的线程通知
System.out.println(name+"消费者结束");
}
}
//生产者等待
private void waitMethod() {
synchronized (object) {
while (true) {
String name=Thread.currentThread().getName();
System.out.println(name+"生产者开始");
try {
this.object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name+"生产者结束");
}
}
}
}
3.生产者与消费者模型
(1)出现阻塞的5种情况(记住)
1)线程调用sleep()方法,主动放弃占用的处理器资源。
2)线程调用了阻塞式IO方法,在该方法返回前,该线程被阻塞。
3)线程视图获得一个同步监视器,但该同步监视器正被其他线程所持有。
4)线程等待某个通知。
5)程序调用了suspend方法将该线程挂起。此方法容易导致死锁,尽量避免使用该方法。
run()方法运行结束后进入销毁阶段,整个线程执行完毕。
(2)生产者消费者模型
1)一个生产者一个消费者并且只生产一次
package com.wschase.shengchanzhexiaofeizhe;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Properties;
import java.util.Queue;
import java.util.concurrent.atomic.AtomicInteger;
/**生产者消费者模型
* Author:WSChase
* Created:2019/1/13
*/
public class ProducerCustomer {
public static void main(String[] args) {
Queue<Goods> queue=new LinkedList<>();
AtomicInteger goodsName=new AtomicInteger(1);//自增长是商品的name的编号
Object monitor=new Object();//监听器--监听器都是Object类
Producer producer=new Producer(queue,monitor,goodsName);
Customer customer=new Customer(queue,monitor);
new Thread(producer).start();
new Thread(customer).start();
}
}
//商品
class Goods{
private final String name;
Goods(String name) {
this.name = name;
}
@Override
public String toString() {
return "Goods{" +
"name='" + name + '\'' +
'}';
}
}
//生产者
class Producer implements Runnable{
//需要把商品放到生产者里面,所以它需要有一个集合
private final Queue<Goods> goods;//注意在这个地方我们一定不能new,因为我们需要实现共享,需要传入进来
private final Object monitor;//监听器-->作为锁来处理
private final AtomicInteger atomicInteger;//自增长
Producer(Queue<Goods> goods, Object monitor, AtomicInteger atomicInteger) {
this.goods = goods;
this.monitor = monitor;
this.atomicInteger = atomicInteger;
}
@Override
public void run() {
synchronized (monitor){
//商品池满了,所以需要等待
if(this.goods.size()==10){//如果等于10表示已经满了
try {
this.monitor.wait();//
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
//这个表示商品池没有满的时候,需要生产者生产商品,每次加1表示每次生产一个
this.goods.add(new Goods(String.valueOf(atomicInteger.getAndAdd(1))));
}
}
}
}
//消费者
class Customer implements Runnable{
private final Queue<Goods> goods;//注意在这个地方我们一定不能new,因为我们需要实现共享,需要传入进来
private final Object monitor;//监听器
Customer(Queue<Goods> goods, Object monitor) {
this.goods = goods;
this.monitor = monitor;
}
@Override
public void run() {
synchronized (monitor){
if(this.goods.isEmpty()){
//如果是空的就通知
this.monitor.notifyAll();
}else {
//如果不是空的就取一个,消费张品
Goods goods=this.goods.poll();
System.out.println(goods);
}
}
}
}
2)一个生产者一个消费者并且生产消费多次
package com.wschase.shengchanzhexiaofeizhe;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Properties;
import java.util.Queue;
import java.util.concurrent.atomic.AtomicInteger;
/**生产者消费者模型
* Author:WSChase
* Created:2019/1/13
*/
public class ProducerCustomer {
public static void main(String[] args) {
Queue<Goods> queue=new LinkedList<>();
AtomicInteger goodsName=new AtomicInteger(1);//自增长是商品的name的编号
Object monitor=new Object();//监听器--监听器都是Object类
Producer producer=new Producer(queue,monitor,goodsName);
Customer customer=new Customer(queue,monitor);
new Thread(producer).start();
new Thread(customer).start();
}
}
//商品
class Goods{
private final String name;
Goods(String name) {
this.name = name;
}
@Override
public String toString() {
return "Goods{" +
"name='" + name + '\'' +
'}';
}
}
//生产者
class Producer implements Runnable{
//需要把商品放到生产者里面,所以它需要有一个集合
private final Queue<Goods> goods;//注意在这个地方我们一定不能new,因为我们需要实现共享,需要传入进来
private final Object monitor;//监听器-->作为锁来处理
private final AtomicInteger atomicInteger;//自增长
Producer(Queue<Goods> goods, Object monitor, AtomicInteger atomicInteger) {
this.goods = goods;
this.monitor = monitor;
this.atomicInteger = atomicInteger;
}
@Override
public void run() {
while (true){
synchronized (monitor){
//商品池满了,所以需要等待
if(this.goods.size()==10){//如果等于10表示已经满了
try {
this.monitor.wait();//
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
//这个表示商品池没有满的时候,需要生产者生产商品,每次加1表示每次生产一个
Goods goods=new Goods(String.valueOf(atomicInteger.getAndAdd(1)));
this.goods.add(goods);
System.out.println("生产者生产"+goods);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
//消费者
class Customer implements Runnable{
private final Queue<Goods> goods;//注意在这个地方我们一定不能new,因为我们需要实现共享,需要传入进来
private final Object monitor;//监听器
Customer(Queue<Goods> goods, Object monitor) {
this.goods = goods;
this.monitor = monitor;
}
@Override
public void run() {
while (true){
synchronized (monitor){
if(this.goods.isEmpty()){
//如果是空的就通知
this.monitor.notifyAll();
}else {
//如果不是空的就取一个,消费张品
Goods goods=this.goods.poll();
System.out.println("消费者消费"+goods);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
3)多个生产者
package com.wschase.shengchanzhexiaofeizhe;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Properties;
import java.util.Queue;
import java.util.concurrent.atomic.AtomicInteger;
/**生产者消费者模型
* Author:WSChase
* Created:2019/1/13
*/
public class ProducerCustomer {
public static void main(String[] args) {
Queue<Goods> queue=new LinkedList<>();
AtomicInteger goodsName=new AtomicInteger(1);//自增长是商品的name的编号
Object monitor=new Object();//监听器--监听器都是Object类
Producer producer1=new Producer(queue,monitor,goodsName);
Producer producer2=new Producer(queue,monitor,goodsName);
Customer customer1=new Customer(queue,monitor);
new Thread(producer1,"生产者1").start();
new Thread(producer2,"生产者2").start();
new Thread(customer1).start();
}
}
//商品
class Goods{
private final String name;
Goods(String name) {
this.name = name;
}
@Override
public String toString() {
return "Goods{" +
"name='" + name + '\'' +
'}';
}
}
//生产者
class Producer implements Runnable{
//需要把商品放到生产者里面,所以它需要有一个集合
private final Queue<Goods> goods;//注意在这个地方我们一定不能new,因为我们需要实现共享,需要传入进来
private final Object monitor;//监听器-->作为锁来处理
private final AtomicInteger atomicInteger;//自增长
Producer(Queue<Goods> goods, Object monitor, AtomicInteger atomicInteger) {
this.goods = goods;
this.monitor = monitor;
this.atomicInteger = atomicInteger;
}
@Override
public void run() {
while (true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (monitor){
//商品池满了,所以需要等待
if(this.goods.size()==10){//如果等于10表示已经满了
try {
this.monitor.wait();//
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
//这个表示商品池没有满的时候,需要生产者生产商品,每次加1表示每次生产一个
Goods goods=new Goods(String.valueOf(atomicInteger.getAndAdd(1)));
this.goods.add(goods);
System.out.println(Thread.currentThread().getName()+"生产"+goods);//打印出谁生产的
}
}
}
}
}
//消费者
class Customer implements Runnable{
private final Queue<Goods> goods;//注意在这个地方我们一定不能new,因为我们需要实现共享,需要传入进来
private final Object monitor;//监听器
Customer(Queue<Goods> goods, Object monitor) {
this.goods = goods;
this.monitor = monitor;
}
@Override
public void run() {
while (true){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (monitor){
if(this.goods.isEmpty()){
//如果是空的就通知
this.monitor.notifyAll();
}else {
//如果不是空的就取一个,消费张品
Goods goods=this.goods.poll();
System.out.println("消费者消费"+goods);
}
}
}
}
}
注意:我们将休眠sleep加在不同的位置,最后结果出现的生产消费将会不同。