一个生产者与一个消费者
-
使用的方法:
wait():使线程停止并释放锁。
notify():叫醒线程。 -
例子
工具类
public class ValueObject {
public static String value="";
}
生产者
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package Thread;
/**
*
* @author zjq
*/
public class Product {
private String lock;
public Product(String lock) {
this.lock = lock;
}
public void setValue() {
try {
synchronized (lock) {
if (!ValueObject.value.equals("")) {
lock.wait();
}
String value = System.currentTimeMillis() + "_" + System.nanoTime();
System.out.println("set的值是" + value);
ValueObject.value = value;
lock.notify();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
消费者
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package Thread;
/**
*
* @author zjq
*/
public class C {
private String lock;
public C(String lock){
super();
this.lock=lock;
}
public void getValue(){
try {
synchronized(lock){
if (ValueObject.value.equals("")) {
lock.wait();
}
System.out.println("get的值是"+ValueObject.value);
ValueObject.value="";
lock.notify();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
线程类
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package Thread;
/**
*
* @author zjq
*/
public class ThreadP extends Thread{
private Product p;
public ThreadP(Product p){
super();
this.p = p;
}
@Override
public void run(){
while (true) {
p.setValue();
}
}
}
线程类
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package Thread;
/**
*
* @author zjq
*/
public class ThreadCc extends Thread{
private C c;
public ThreadCc(C c){
super();
this.c = c;
}
@Override
public void run(){
while (true) {
c.getValue();
}
}
//在这里运行
public static void main(String[] args) {
String lock=new String("");
Product p = new Product(lock);
C c = new C(lock);
ThreadP pThread = new ThreadP(p);
ThreadCc rThread = new ThreadCc(c);
pThread.start();
rThread.start();
}
}
结果
set的值是1543303341507_1059415405779753
get的值是1543303341507_1059415405779753
set的值是1543303341507_1059415406123851
get的值是1543303341507_1059415406123851
set的值是1543303341508_1059415406526419
get的值是1543303341508_1059415406526419
set的值是1543303341508_1059415406739753
get的值是1543303341508_1059415406739753
set的值是1543303341508_1059415406818765
get的值是1543303341508_1059415406818765
set的值是1543303341508_1059415406979950
get的值是1543303341508_1059415406979950
set的值是1543303341508_1059415407143111
get的值是1543303341508_1059415407143111
多个消费者多个生产者
-
使用的方法
wait():停止线程释放锁。
notifyall():叫醒所有的线程。 -
例子
工具类
public class ValueObject {
public static String value="";
}
生产者
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package Thread;
/**
*
* @author zjq
*/
public class Product {
private String lock;
public Product(String lock) {
this.lock = lock;
}
public void setValue() {
try {
synchronized (lock) {
if (!ValueObject.value.equals("")) {
System.out.println("生产者 "+Thread.currentThread().getName()+"waiting 了 *");
lock.wait();
}
String value = System.currentTimeMillis() + "_" + System.nanoTime();
System.out.println("生产者 " + Thread.currentThread().getName()+"RUNNING 了");
ValueObject.value = value;
lock.notify();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
消费者
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package Thread;
/**
*
* @author zjq
*/
public class C {
private String lock;
public C(String lock){
super();
this.lock=lock;
}
public void getValue(){
try {
synchronized(lock){
while (ValueObject.value.equals("")) {
System.out.println("消费者 "+Thread.currentThread().getName()+"waiting 了 *");
lock.wait();
}
System.out.println("消费者 " + Thread.currentThread().getName()+"RUNNING 了");
ValueObject.value="";
lock.notifyAll();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
线程类
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package Thread;
/**
*
* @author zjq
*/
public class ThreadP extends Thread{
private Product p;
public ThreadP(Product p){
super();
this.p = p;
}
@Override
public void run(){
while (true) {
p.setValue();
}
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package Thread;
/**
*
* @author zjq
*/
public class ThreadCc extends Thread{
private C c;
public ThreadCc(C c){
super();
this.c = c;
}
@Override
public void run(){
while (true) {
c.getValue();
}
}
public static void main(String[] args) throws InterruptedException {
String lock=new String("");
Product p = new Product(lock);
C c = new C(lock);
ThreadP[] pThread = new ThreadP[2];
ThreadCc[] rThread = new ThreadCc[2];
for(int i=0;i<2;i++){
pThread[i]=new ThreadP(p);
pThread[i].setName("生产者"+(i+1));
rThread[i]=new ThreadCc(c);
rThread[i].setName("消费者"+(i+1));
pThread[i].start();
rThread[i].start();
}
Thread.sleep(5000);
Thread[] threadArray = new Thread[Thread.currentThread().getThreadGroup().activeCount()];
Thread.currentThread().getThreadGroup().enumerate(threadArray);
for(int i=0;i<threadArray.length;i++){
System.out.println(threadArray[i].getName()+" "+threadArray[i].getState());
}
}
}
运行结果
生产者 生产者1RUNNING 了
消费者 消费者2RUNNING 了
消费者 消费者2waiting 了 *
消费者 消费者1waiting 了 *
生产者 生产者2RUNNING 了
生产者 生产者2waiting 了 *
........
结果分析:如果不适用notifyall的话,生产者之间相互唤醒的话就容易造线程的假死状态。