Java多线程-同步:synchronized 和线程通信:生产者消费者模式
大家伙周末愉快,小乐又来给大家献上技术大餐。上次是说到了Java多线程的创建和状态|乐字节,接下来,我们再来接着说Java多线程-同步:synchronized 和线程通信:生产者消费者模式。
一、同步:synchronized
多个线程同时访问一个对象,可能造成非线程安全,数据可能错误,所谓同步:就是控制多个线程同时访就是控制多线程操作同一个对象时,注意是同一个对象,数据的准确性, 确保数据安全,但是加入同步后因为需要等待,所以效率相对低下。
如:一个苹果,自己一个人去咬怎么都不会出问题,但是多个人同时去咬,这个时候如果控制不好,就可能会咬到对方了。 再强调一下是一个苹果。
12306 中的火车票,为什么抢到票时,需要等待,锁定席位才付款?这就是确保一张票只能一个人去购买。
1、同步块
synchronized +块:同步块
synchronized (引用类型|对象|类.class) {
}
2、同步方法
修饰符 synchronized 返回类型|void 方法签名{
}
3、死锁
过多的同步容易死锁
/**
* 死锁:容易造成死锁
* @author Administrator
*
*/
public class TestDeadLock {
/**
* @param args
*/
public static void main(String[] args) {
Object obj1 =new Object();
Object obj2 =new Object();
new A(obj1,obj2).start();
new B(obj1,obj2).start();
} }
class A extends Thread{
Object obj1 ;
Object obj2;
public A() {
}
public A(Object obj1, Object obj2) {
super();
this.obj1 = obj1;
this.obj2 = obj2;
}
@Override
public void run() {
synchronized(obj1){
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(obj2){
}
}
System.out.println("给我烟");
} }
class B extends Thread{
Object obj1 ;
Object obj2;
public B() {
}
public B(Object obj1, Object obj2) {
super();
this.obj1 = obj1;
this.obj2 = obj2;
}
@Override
public void run() {
synchronized(obj2){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(obj1){
} }
System.out.println("给我钱");
}
}
二、线程通信:生产者消费者模式
线程通信的目标是使线程间能够互相发送信号。另一方面,线程通信使线程能够等待其
他线程的信号。
Java 有一个内建的等待机制来允许线程在等待信号的时候变为非运行状态。
java.lang.Object 类定义了三个方法,wait()、notify()和 notifyAll()来实现这个等待机制。一个线程一旦调用了任意对象的 wait()方法,就会变为非运行状态,直到另一个线程调用了同一个对象的 notify()方法。为了调用 wait()或者 notify(),线程必须先获得那个对象的锁。也就是说,线程必须在同步块里调用 wait()或者 notify()。
以下为一个使用了 wait()和 notify()实现的线程间通信的共享对象:
/**
* 街道
* @author Administrator
*
*/
public class Street {
//红绿灯
//false 红灯 -->人等 车走 -->换灯 通知人走
//true 绿灯 -->车等 人走 -->换灯 通知车走
private boolean flag=false;
//东西向 -->人道
public synchronized void west(){
if(flag==false){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("东西向-->人走");
//换灯
this.flag =false;
this.notify(); //唤醒等待者
}
//南北向 车道
public synchronized void north(){
if(flag==true){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
} }
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("南北向-->车走");
//换灯
this.flag =true;
this.notify(); //唤醒等待者
}
}
class Person extends Thread {
private Street s ;
public Person(Street s) {
this.s = s; }
public void run() {
for(int i=0;i<10;i++){
s.west(); //东西向
}
}
}
class Car extends Thread {
private Street s ;
public Car(Street s) {
this.s = s; }
public void run() {
for(int i=0;i<10;i++){
s.north();
}
}
}
Java多线程的同步和线程通信就介绍到这里,更多技术干货请关注乐字节。乐字节原创!
Java多线程-同步:synchronized 和线程通信:生产者消费者模式的更多相关文章
- .net学习之多线程、线程死锁、线程通信 生产者消费者模式、委托的简单使用、GDI(图形设计接口)常用的方法
1.多线程简单使用(1)进程是不执行代码的,执行代码的是线程,一个进程默认有一个线程(2)线程默认情况下都是前台线程,要所有的前台线程退出以后程序才会退出,进程里默认的线程我们叫做主线程或者叫做UI线 ...
- 第23章 java线程通信——生产者/消费者模型案例
第23章 java线程通信--生产者/消费者模型案例 1.案例: package com.rocco; /** * 生产者消费者问题,涉及到几个类 * 第一,这个问题本身就是一个类,即主类 * 第二, ...
- Java线程通信-生产者消费者问题
线程通信示例——生产者消费者问题 这类问题描述了一种情况,假设仓库中只能存放一件产品,生产者将生产出来的产品放入仓库,消费者将仓库中的产品取走消费.假设仓库中没有产品,则生产者可以将 产品放入仓库,有 ...
- Java多线程同步 synchronized 关键字的使用
代表这个方法加锁,相当于不管哪一个线程A每次运行到这个方法时,都要检查有没有其它正在用这个方法的线程B(或者C D等),有的话要等正在使用这个方法的线程B(或者C D)运行完这个方法后再运行此线程A, ...
- java多线程回顾4:线程通信
1.线程的协调运行 线程的协调运行有一个经典案例,即生产者和消费者问题. 假设有一个货架,生产者往货架上放货物,消费者从货架上取货物. 为了方便讲解,制定一个规则,生产者每放上一个货物,消费者就得取走 ...
- Java多线程使用wait和notify实现生产者消费者模型
Java多线程使用wait和notify这两个关键字的学习,通过实现生成者与消费者来成对研究比较科学. 从两个字的意义来讲就是等待与通知这个简单道理. 现在先模拟一个缓存区存储,是用一个list实现的 ...
- Java自学-多线程 同步synchronized
Java 多线程同步 synchronized 多线程的同步问题指的是多个线程同时修改一个数据的时候,可能导致的问题 多线程的问题,又叫Concurrency 问题 步骤 1 : 演示同步问题 假设盖 ...
- python 并发编程 锁 / 信号量 / 事件 / 队列(进程间通信(IPC)) /生产者消费者模式
(1)锁:进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的,而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理. 虽然使用加锁的形式实现了 ...
- java多线程同步以及线程间通信详解&消费者生产者模式&死锁&Thread.join()(多线程编程之二)
本篇我们将讨论以下知识点: 1.线程同步问题的产生 什么是线程同步问题,我们先来看一段卖票系统的代码,然后再分析这个问题: package com.zejian.test; /** * @author ...
随机推荐
- JAVA添加WORD文档批注
本文将介绍在Java程序中如何给Word文档中的指定字符串添加批注.前文中,主要介绍的是针对某个段落来添加批注,以及回复.编辑.删除批注的方法,如果需要针对特定关键词或指定字符串来设置批注,可以参考本 ...
- django-发送文件
客户端授权密码”,勾选“开启”,弹出新窗口填写手机验证码. settings.py配置 EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBac ...
- JPA注解开发
JPA注解开发 jpa是sun公司的一个ORM规范,只有接口和注解,没有具体实现. jpa是EJB3中的. 单表常用注解 书写注解,并配置 @Entity @Table(name = "c_ ...
- Django ContentTypes框架使用场景
Django contenttypes是一个非常有用的框架,主要用来创建模型间的通用关系(generic relation).不过由于其非常抽象, 理解起来并不容易.当你创建一个django项目的时候 ...
- qtcreator cannot find catkin packages
adding /opt/ros/kinetic to CMAKE_PREFIX_PATH in Project -> build environment only /opt/ros/kineti ...
- LeetCode 787. Cheapest Flights Within K Stops
原题链接在这里:https://leetcode.com/problems/cheapest-flights-within-k-stops/ 题目: There are n cities connec ...
- BZOJ 1758: [Wc2010]重建计划 01分数规划+点分治+单调队列
code: #include <bits/stdc++.h> using namespace std; #define setIO(s) freopen(s".in", ...
- learning java FileOutputStream
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStrea ...
- WinDbg常用命令系列---显示引用的内存(dda、ddp、ddu、dpa、dpp、dpu、dqa、dqp、dqu)
命令dda, ddp, ddu, dpa, dpp, dpu, dqa, dqp, 和 dqu在指定位置显示指针,取消对该指针的引用,然后以各种格式显示结果位置的内存. ddp [Options] [ ...
- 一篇来自hasura graphql-engine 百万级别live query 的实践
转自:https://github.com/hasura/graphql-engine/blob/master/architecture/live-queries.md Scaling to 1 mi ...