java多线程(同步和死锁,生产者和消费者问题)
2024-10-18 15:44:31
首先我们来看看同步与死锁:
所谓死锁。这是A有banana,B有apple。
A至B说:你把apple对我来说,,我会banana给你。
B至A说:你把banana对我来说,,我会apple给你。
可是A和B都在等待对方的答复。那么这样终于的结果就是A得不到apple,B也得不到banana。这样的死循环就是死锁。
于是我们能够模拟上面的描写叙述,写出下面代码:
类A代表A这个人。
public class A {
public void say(){
System.out.println("A said to B: if you give me the apple, I will give you the banana.");
}
public void get(){
System.out.println("A get the apple.");
}
}
类B代表B这个人,
public class B {
public void say(){
System.out.println("B said to A: if you give me the banana, I will give you the apple.");
}
public void get(){
System.out.println("B get the banana.");
}
}
类ThreadDeadLock代表死锁类,
public class ThreadDeadLock implements Runnable{
private static A a=new A();
private static B b=new B();
public boolean flag=false;
public void run(){
if(flag){
synchronized(a){
a.say();
try{
Thread.sleep(500);
}catch(InterruptedException e){
e.printStackTrace();
}
synchronized(b){
a.get();
}
}
}else{
synchronized(b){
b.say();
try{
Thread.sleep(500);
}catch(InterruptedException e){
e.printStackTrace();
}
synchronized(a){
b.get();
}
}
}
}
}
以下是主类:
public class Main{
public static void main(String[] args){
ThreadDeadLock t1=new ThreadDeadLock();
ThreadDeadLock t2=new ThreadDeadLock();
t1.flag=true;
t2.flag=false;
Thread thA=new Thread(t1);
Thread thB=new Thread(t2);
thA.start();
thB.start();
}
}
程序执行结果:
A said to B: if you give me the apple, I will give you the banana.
B said to A: if you give me the banana, I will give you the apple.
从以上的程序执行,我们能够发现,两个线程都在等待对方的执行完毕。这样,程序也就无法继续执行。从而造成了死锁执行现象。
以下我们来看生产者与消费者问题:
所谓生产者与消费者问题,非常easy,过程就是生产者不断生产产品。消费者不断取走产品。
Producer生产product。Consumer消费product。
于是,我们先定义product类:
public class Product {
private String name="product";
private boolean flag=false;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public synchronized void set(String name){
if(!flag){
try{
super.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
this.setName(name);
try{
Thread.sleep(300);
}catch(InterruptedException e){
e.printStackTrace();
}
flag=false;
super.notify();
}
public synchronized void get(){
if(flag){
try{
super.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
try{
Thread.sleep(300);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(this.getName());
flag=true;
super.notify();
}
}
这里添加了等待与唤醒,并添加一个标志位flag,flag为true时,表示能够生产。但不能取走,此时假设线程执行到了消费者线程,则应该等待,假设flag为false,则表示能够取走,可是不能生产,假设生产者线程执行,则应该等待。
Producer类:
public class Producer implements Runnable{
private Product product=null;
public Producer(Product product){
this.product=product;
}
public void run(){
for(int i=0;i<50;++i){
this.product.set("product");
}
}
}
Consumer类:
public class Consumer implements Runnable{
private Product product=null;
public Consumer(Product product){
this.product=product;
}
public void run(){
for(int i=0;i<50;++i){
try{
Thread.sleep(100);
}catch(InterruptedException e){
e.printStackTrace();
}
this.product.get();
}
}
}
然后是主类:
public class Main{
public static void main(String[] args){
Product product=new Product();
Producer pro=new Producer(product);
Consumer con=new Consumer(product);
new Thread(pro).start();
new Thread(con).start();
}
}
所以我们知道。生产者每生产一个产品,删除产品的消费者,删除每个消费者产品。我们必须等待生产者生产。
最新文章
- Underscore 整体架构浅析
- 电容参数:X5R,X7R,Y5V,COG 详解
- Jsp 错题分析
- centos 安装rmagick 2.13.4出错
- 基于angular写的一个todolist
- tomcat 大并发报错 Maximum number of threads (200) created for connector with address null and port 8080
- .net学习之多线程、线程死锁、线程通信 生产者消费者模式、委托的简单使用、GDI(图形设计接口)常用的方法
- javascript 字符串相关知识汇总
- zw版【转发&#183;台湾nvp系列Delphi例程】HALCON DivImage2
- 【网络流24题】No. 17 运输问题 (费用流)
- Effective Modern C++ Item 37:确保std::thread在销毁时是unjoinable的
- .NET Core多平台开发体验[1]: Windows
- 关于CSDN, cnblog, iteye和51cto四个博客网站的比较与分析
- SSO单点登录一:cas单点登录防止登出退出后刷新后退ticket失效报500错,也有退出后直接重新登录报票根验证错误
- PostgreSQL9.6.2的WINDOWS下安装
- linux下关闭网络命令
- Docker 错误 docker: invalid reference format. 的解决
- selenium2 webdriver 常用的python 函数
- php 调试的常用方法
- bootstrap 警告框单个删除