多线程的并发与协作
程序员文章站
2022-04-19 10:27:50
...
多线程可以提高一个项目的运行效率, 多线程之间的协作也不可避免,先举一个简单的例子:先介绍第一个类
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一样
上一篇: 一文学会JVM配置参数与工具使用
下一篇: openwrt从0开始-目录