大家伙周末愉快,小乐又来给大家献上技术大餐。上次是说到了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 和线程通信:生产者消费者模式的更多相关文章

  1. .net学习之多线程、线程死锁、线程通信 生产者消费者模式、委托的简单使用、GDI(图形设计接口)常用的方法

    1.多线程简单使用(1)进程是不执行代码的,执行代码的是线程,一个进程默认有一个线程(2)线程默认情况下都是前台线程,要所有的前台线程退出以后程序才会退出,进程里默认的线程我们叫做主线程或者叫做UI线 ...

  2. 第23章 java线程通信——生产者/消费者模型案例

    第23章 java线程通信--生产者/消费者模型案例 1.案例: package com.rocco; /** * 生产者消费者问题,涉及到几个类 * 第一,这个问题本身就是一个类,即主类 * 第二, ...

  3. Java线程通信-生产者消费者问题

    线程通信示例——生产者消费者问题 这类问题描述了一种情况,假设仓库中只能存放一件产品,生产者将生产出来的产品放入仓库,消费者将仓库中的产品取走消费.假设仓库中没有产品,则生产者可以将 产品放入仓库,有 ...

  4. Java多线程同步 synchronized 关键字的使用

    代表这个方法加锁,相当于不管哪一个线程A每次运行到这个方法时,都要检查有没有其它正在用这个方法的线程B(或者C D等),有的话要等正在使用这个方法的线程B(或者C D)运行完这个方法后再运行此线程A, ...

  5. java多线程回顾4:线程通信

    1.线程的协调运行 线程的协调运行有一个经典案例,即生产者和消费者问题. 假设有一个货架,生产者往货架上放货物,消费者从货架上取货物. 为了方便讲解,制定一个规则,生产者每放上一个货物,消费者就得取走 ...

  6. Java多线程使用wait和notify实现生产者消费者模型

    Java多线程使用wait和notify这两个关键字的学习,通过实现生成者与消费者来成对研究比较科学. 从两个字的意义来讲就是等待与通知这个简单道理. 现在先模拟一个缓存区存储,是用一个list实现的 ...

  7. Java自学-多线程 同步synchronized

    Java 多线程同步 synchronized 多线程的同步问题指的是多个线程同时修改一个数据的时候,可能导致的问题 多线程的问题,又叫Concurrency 问题 步骤 1 : 演示同步问题 假设盖 ...

  8. python 并发编程 锁 / 信号量 / 事件 / 队列(进程间通信(IPC)) /生产者消费者模式

    (1)锁:进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的,而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理. 虽然使用加锁的形式实现了 ...

  9. java多线程同步以及线程间通信详解&消费者生产者模式&死锁&Thread.join()(多线程编程之二)

    本篇我们将讨论以下知识点: 1.线程同步问题的产生 什么是线程同步问题,我们先来看一段卖票系统的代码,然后再分析这个问题: package com.zejian.test; /** * @author ...

随机推荐

  1. 15 分钟学会使用 Git 和远程代码库

    Git是个了不起但却复杂的源代码管理系统.它能支持复杂的任务,却因此经常被认为太过复杂而不适用于简单的日常工作.让我们诚实一记吧:Git是复杂的,我们不要装作它不是.但我仍然会试图教会你用(我的)基本 ...

  2. vue之组件通信

    vue组件通信一般分为以下几种情况: 1.父子组件通信: 2.兄弟组件通信: 3.跨多层级组件通信: 一.父子通信        父组件通过props传递数据给子组件,子组件通过emit发送事件传递数 ...

  3. 更丰富的符号工具包 Font Awesome

    我时常想要在此类文档中通过一些图形符号来表达更丰富的含义或是对段落进行标注,例如使用 Emoji.然而 Emoji 在这方面仍然有存在一些不足,如: 颜色与文字风格不统一, 在不同系统的平台上显示不统 ...

  4. 20199302《Linux内核原理与分析》第十二周作业

    ShellShock攻击实验 什么是ShellShock? Shellshock,又称Bashdoor,是在Unix中广泛使用的Bash shell中的一个安全漏洞,首次于2014年9月24日公开.许 ...

  5. js 鼠标事件详细

    常用的几个类型 onClick HTML: 2 | 3 | 3.2 | 4 Browser: IE3 | N2 | O3 鼠标点击事件,多用在某个对象控制的范围内的鼠标点击 onDblClick HT ...

  6. jsp之大文件分段上传、断点续传

    1,项目调研 因为需要研究下断点上传的问题.找了很久终于找到一个比较好的项目. 在GoogleCode上面,代码弄下来超级不方便,还是配置hosts才好,把代码重新上传到了github上面. http ...

  7. MuPAD使用总结

    MuPAD使用总结 一.打开notebook界面的方法: 二.notebook界面的三种区域 (一).输入区域 输入区域在打开来的时候就有,就是,但是之后如果还想再加,可以点击上方红色框内的图标. 这 ...

  8. 干货 | 10分钟教你用column generation求解vehicle routing problems

    OUTLINE 前言 VRPTW description column generation Illustration code reference 00 前言 此前向大家介绍了列生成算法的详细过程, ...

  9. TCP网络程序设计

    tcp_server.c #include<stdio.h>#include<sys/socket.h>#include<string.h>#include< ...

  10. Android入门教程(三)

    对Android五大布局的描述,分别是 FrameLayout (框架布局),LinearLayout (线性布局),AbsoluteLayout (绝对布局),RelativeLayout (相对布 ...