多线程可以提高一个项目的运行效率, 多线程之间的协作也不可避免,先举一个简单的例子:先介绍第一个类
package HelloWorld;
public class ThradStudy {
private String response ;
private Object synObj = new Object();
public void start(){
System.out.println("AAAAAAAAA");
try{
synchronized (synObj) {
synObj.wait(10000);
}
}
catch(Exception e ){
}
System.out.println(response);
}
public void notify(String a ){
response = a ;
synchronized(synObj){
synObj.notifyAll();
}
}
}
这个类有两个私有字段,一个是字符串str , 一个是锁synObj对象,在另一个类中,我们先声明一个ThradStudy对象,在main方法中,启动两个线程,一个线程负责执行start,一个线程负责3秒后唤醒另一个线程代码如下
package HelloWorld;
public class notyFyClass {
public static ThradStudy test = new ThradStudy() ;
public static void main(String[] args) {
new Thread(new Runnable(){
@Override
public void run() {
test.start();
}
}).start();
new Thread(new Runnable(){
@Override
public void run() {
try {
Thread.sleep(3000) ;
} catch (InterruptedException e) {
e.printStackTrace();
}
String str = "唤醒" ;
test.notify(str);
}
}).start();
}
}
执行结果可以看到,先输出AAAAAAA,而后输出“唤醒”;
这个例子可能不太容易理解,下面分别通过synchronized和Lock来实现生产者和消费者
一、Lock
package HelloWorld;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ProduceCustomer {
public static void main(String[] args) {
Resouse sss = new Resouse();
Thread pro = new Thread(new Producer(sss));
Thread cus = new Thread(new Customer(sss));
pro.start();
cus.start();
}
}
class Resouse{
private Lock lock = new ReentrantLock();
private Condition conditionPro = lock.newCondition() ;
private Condition conditionCus = lock.newCondition() ;
private String name ;
private int count = 0 ;
private boolean flag = false ; //false 表示没有商品需要生产
public void set(String name) throws Exception{
lock.lock();
try{
if(flag){
conditionPro.await();
}
count++ ;
this.name = name+count ;
conditionCus.signal();
flag = true ;
System.out.println("生产 "+this.name);
}
finally{
lock.unlock();
}
}
public void pro() throws Exception{
lock.lock() ;
try{
if(!flag){
conditionCus.await() ;
}
flag = false ;
System.out.println("消费"+this.name);
conditionPro.signal();
}
finally{
lock.unlock();
}
}
}
class Producer extends Resouse implements Runnable{
private Resouse r ;
public Producer(Resouse re){
super();
r = re ;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
try {
r.set("篮球") ;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class Customer extends Resouse implements Runnable{
private Resouse r ;
public Customer(Resouse re ){
super();
r = re ;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
try {
r.pro() ;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
里面有一个resource类,他里面有一个set和pro方法,set方法负责生产部件,pro方法负责消费部件,如果没有部件就不能消费只能生产,在这里set方法中,如果有部件需要生产则生产一个部件并唤醒消费,如果不需要生产则睡眠,等待消费线程消费完部件后唤醒,Producer类和Customer则是实现线程不断的执行生产和消费
二、synchronized
package HelloWorld;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ProduceCustomer {
public static void main(String[] args) {
Resouse sss = new Resouse();
Thread pro = new Thread(new Producer(sss));
Thread cus = new Thread(new Customer(sss));
pro.start();
cus.start();
}
}
class Resouse{
private Object synObj = new Object();
private String name ;
private int count = 0 ;
private boolean flag = false ; //false 表示没有商品需要生产
public void set(String name) throws Exception{
synchronized(synObj){
if(flag){
synObj.wait();
}
count++ ;
this.name = name+count ;
synObj.notify();
flag = true ;
System.out.println("生产 "+this.name);
}
}
public void pro() throws Exception{
synchronized(synObj){
if(!flag){
synObj.wait() ;
}
flag = false ;
System.out.println("消费"+this.name);
synObj.notify();
}
}
}
class Producer extends Resouse implements Runnable{
private Resouse r ;
public Producer(Resouse re){
super();
r = re ;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
try {
r.set("篮球") ;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class Customer extends Resouse implements Runnable{
private Resouse r ;
public Customer(Resouse re ){
super();
r = re ;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
try {
r.pro() ;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
实现原理和Lock一样