Java多线程-Lock锁的使用,以及生产者和消费者的实现
来源:互联网 发布:数据存储格式 编辑:程序博客网 时间:2024/06/05 16:27
本文中将主要介绍Java多线程编程基础中的Lock锁对象的使用,以及如何一步一步实现Java代码的生产者与消费者;
1、Java中如何使用Lock锁以及死锁问题的描述
2、Java实现生产者与消费者的过程(一步一步优化的步骤)
1、Java中如何使用Lock锁以及死锁问题的描述
LOCK锁的出现:为了更清晰的表达如何加锁和释放锁,JDK5以后提供了一个新的锁对象LOCK;
Lock锁中最重要的个方法:
void lock()
void unlock()
下面就是Lock锁的一个简单的演示Demo,之后的死锁问题也会使用Lock锁来进行表现;
1)例子一:利用Lock对象实现售票机制:
SellTicket.java
import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class SellTicket implements Runnable { // 定义票 private int tickets = 100; // 定义锁对象 private Lock lock = new ReentrantLock(); @Override public void run() { while (tickets > 0) { // 之所以不带catch是因为保证在出错的情况下保证锁的释放 try{ // 加锁 lock.lock(); if (tickets > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets-- + "张票" ); } } finally { // 释放锁 lock.unlock(); } } }}
SellTicketDemo.java
public class SellTicketDemo { public static void main(String[] args) { // 创建资源对象 SellTicket st = new SellTicket(); // 创建窗口 Thread thread1 = new Thread(st, "窗口一"); Thread thread2 = new Thread(st, "窗口二"); Thread thread3 = new Thread(st, "窗口三"); // 开启线程 thread1.start(); thread2.start(); thread3.start(); } }
运行效果:
可以看见线程在运行的时候,基本上都是成片运行的,并没有比较好的交叉运行
2)例子二:利用Lock实现死锁机制
MyLock.java
/** * 创建两把锁可以直接调用 * @author YQ * */public class MyLock { //创建两把锁对象 public static final Object objA = new Object(); public static final Object objB = new Object();}
DieLock.java
public class DieLock extends Thread { private boolean flag; public DieLock(boolean flag) { this.flag = flag; } @Override public void run() { if (flag) { synchronized (MyLock.objA) { System.out.println("if ObjA"); synchronized (MyLock.objB) { System.out.println("if ObjB"); } } } else { synchronized (MyLock.objB) { System.out.println("else ObjB"); synchronized (MyLock.objA) { System.out.println("else ObjA"); } } } }}
DieLockDemo.java
/** * 同步的弊端: * A:效率低 * B:容易产生死锁 * 死锁: * 两个或者两个以上的线程在争夺资源的过程中,发生的一种互相等待的现象 * @author YQ */public class DieLockDemo { public static void main(String[] args) { DieLock dieLock1 = new DieLock(true); DieLock dieLock2 = new DieLock(false); dieLock1.start(); dieLock2.start(); }}
运行效果:
2、Java实现生产者与消费者的过程(一步一步优化的步骤)
1)初始实现,定义一个Student的JavaBean的类,然后通过set保存Student的数据作为生产者,之后通过get取出Student的数据作为消费者,但是以下的实现仅仅只有一次!
Student.java
public class Student { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; }}
SetThread.java
public class SetThread extends Thread{ private Student student; public SetThread(Student student) { super(); this.student = student; } @Override public void run() { student.setName("admin"); student.setAge(24); }}
GetThread.java
public class GetThread extends Thread { private Student student; public GetThread(Student student) { super(); this.student = student; } @Override public void run() { System.out.println(student.getName() + "====" + student.getAge()); }}
StudentDemo.java
public class StudentDemo { public static void main(String[] args) { // 创建两个线程的共用资源 Student student = new Student(); // 创建生产者和消费者 SetThread thread1 = new SetThread(student); GetThread thread2 = new GetThread(student); //开启生产者和消费者线程 thread1.start(); thread2.start(); }}
运行效果:
2)进一步的循环实现多次生产多次消费,使用的是同步的方式
Student.java代码同上!
GetThread.java
public class GetThread extends Thread { private Student student; public GetThread(Student student) { super(); this.student = student; } @Override public void run() { while (true) { synchronized (student) { System.out.println(student.getName() + "====" + student.getAge()); } } }}
SetThread.java
public class SetThread extends Thread{ private Student student; private int x = 0; public SetThread(Student student) { super(); this.student = student; } @Override public void run() { while (true) { //必须是相同的同一把锁 synchronized (student) { if (x%2 == 0) { student.setName("admin"); student.setAge(24); } else { student.setName("manager"); student.setAge(28); } x++; } } }}
StudentDemo.java
public class StudentDemo { public static void main(String[] args) { // 创建两个线程的共用资源 Student student = new Student(); // 创建生产者和消费者 SetThread thread1 = new SetThread(student); GetThread thread2 = new GetThread(student); //开启生产者和消费者线程 thread1.start(); thread2.start(); }}
运行效果(停止的时候出现的ad没有完整与线程的实现没有关系,主要是因为命令窗口的缓冲没有完整的原因):
3)真正实现生产者与消费者:生产者生产后消费者才可以消费,消费者消费之后生产者才可以生产如此往复:
Student.java
public class Student { private String name; private int age; //默认情况下不存在数据 private boolean flag; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public boolean isFlag() { return flag; } public void setFlag(boolean flag) { this.flag = flag; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; }}
SetThread.java
public class SetThread extends Thread{ private Student student; private int x = 0; public SetThread(Student student) { super(); this.student = student; } @Override public void run() { while (true) { // 必须是相同的同一把锁 synchronized (student) { // 判断 if (student.isFlag()) { try { student.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if (x%2 == 0) { student.setName("admin"); student.setAge(24); } else { student.setName("manager"); student.setAge(28); } x++; // 修改标记 student.setFlag(true); student.notify(); } } }}
GetThread.java
public class GetThread extends Thread { private Student student; public GetThread(Student student) { super(); this.student = student; } @Override public void run() { while (true) { synchronized (student) { if (!student.isFlag()) { try { student.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println(student.getName() + "====" + student.getAge()); student.setFlag(false); student.notify(); } } }}
运行效果:
StudentDemo.java
/** * 等待唤醒: * Object类中提供了三个方法: * wait():等待; * notify():唤醒单个线程; * notifyAll():唤醒所有线程; * @author YQ * */public class StudentDemo { public static void main(String[] args) { // 创建两个线程的共用资源 Student student = new Student(); // 创建生产者和消费者 SetThread thread1 = new SetThread(student); GetThread thread2 = new GetThread(student); //开启生产者和消费者线程 thread1.start(); thread2.start(); }}
运行效果:
- Java多线程-Lock锁的使用,以及生产者和消费者的实现
- java多线程---等待/唤醒以及生产者消费者经典同步Lock的实现
- 使用Lock的Condition实现生产者消费者
- 使用jdk1.5的多线程 lock condition 实现方式实现 生产者消费者问题
- 使用多线程实现生产者和消费者的机制
- 关于Java多线程实现生产者和消费者的问题
- java 多线程的生产者-消费者 实现
- Java多线程生产者和消费者的例子
- Lock锁 实现生产者和消费者问题
- 多线程-生产者消费者lock锁
- 使用Java的BlockingQueue实现生产者-消费者
- 使用Java的BlockingQueue实现生产者-消费者
- 使用Java的BlockingQueue实现生产者-消费者
- 使用Java的BlockingQueue实现生产者-消费者
- 使用Java的BlockingQueue实现生产者-消费者
- 使用Java的BlockingQueue实现生产者-消费者
- 生产者和消费者问题的Java实现
- Java实现的生产者和消费者
- saiku安装方法总结
- nodejs入门必须知道的内容
- N个加油站问题
- Unity3D-UI-Canvas
- innodb的多版本控制
- Java多线程-Lock锁的使用,以及生产者和消费者的实现
- Codeforces Round #350(Div 2)
- 完全不知道怎么取标题,但是不进来看看也许会后悔--其实我一开始想写关于virtual 函数的
- 线程并发总结
- LeetCode 022 Generate Parentheses
- Vulkan教程-Vulkan实例(代码示例)
- VTK:基于Qt的VTK右击菜单实现
- error :No module named google.protobuf.internal
- android 二进制流保存为bmp文件