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多线程的同步和线程通信就介绍到这里,更多技术干货请关注乐字节。乐字节原创!

原文地址:https://www.cnblogs.com/lotbyte/p/11334852.html

时间: 2025-01-03 15:43:04

Java多线程-同步:synchronized 和线程通信:生产者消费者模式的相关文章

Java多线程编程4--Lock的实例--实现生产者/消费者模式:一对一、多对多交替打印

1.实现生产者/消费者模式:一对一交替打印 public class MyService { private ReentrantLock lock= new ReentrantLock(); private Condition condition = lock.newCondition(); private boolean hasValue = false; public void set() { try{ lock.lock(); while (hasValue == true) { cond

多线程的并发执行应用(生产者消费者模式)

在实际的开发中我们为了提高CPU的利用率,也提高程序的执行效率,我们经常使用多线程进行对数据进行并发处理,下面我举一个多线程并发执行的实例,大致意思就是 一个简单的生产者消费者模式,二个线程进行存数据,一个线程进行取数据. import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; public class BlockingQueueTest { /** * @param a

线程协作---生产者消费者模式之“管程法”实现

1 package cn.ftf.threadcooperation; 2 /** 3 * 协作模型:生产者消费者模式实现方式一:管程法,借助一个缓冲区 4 * @author 房廷飞 5 * 6 */ 7 8 public class CoTest01 { 9 public static void main(String[] args) { 10 SyContainer sy=new SyContainer(); 11 Productor pro=new Productor(sy); 12 p

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

线程通信示例--生产者消费者问题 这类问题描述了一种情况,假设仓库中只能存放一件产品,生产者将生产出来的产品放入仓库,消费者将仓库中的产品取走消费.假设仓库中没有产品,则生产者可以将 产品放入仓库,有产品,则停止生产并等待,直到仓库中的产品被消费这取走为止. 如果仓库中放油产品,则消费者可以将产品取走消费,否则停止消费并等待,直到 仓库中再次放入产品为止. 显然,这是一个同步问题,生产者和消费这共享同一资源, 并且生产者和消费这之间彼此依赖,互为条件向前推进.Java提供了3个方法解决了线程间的

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

代表这个方法加锁,相当于不管哪一个线程A每次运行到这个方法时,都要检查有没有其它正在用这个方法的线程B(或者C D等),有的话要等正在使用这个方法的线程B(或者C D)运行完这个方法后再运行此线程A,没有的话,直接运行它包括两种用法:synchronized 方法和 synchronized 块. JAVA多线程买票案例 synchronized 同步 用synchronized 块实现同步 public static void main(String[] args) { // runable对

Java多线程同步 – synchronized 用法

1.      利用类对象进行同步 当两个线程访问同一个类对象时,发生竞争.同步加锁的是对象,而不是代码. package thrds; public class FiveThread { public static void main(String args[]) { ThTst obj = new ThTst(); Thread t1 = new Thread(obj); // 两个线程用同一个对象,发生互斥(属于对象互斥) Thread t2 = new Thread(obj); t1.s

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

本篇我们将讨论以下知识点: 1.线程同步问题的产生 什么是线程同步问题,我们先来看一段卖票系统的代码,然后再分析这个问题: [java] view plain copy print? package com.zejian.test; /** * @author zejian * @time 2016年3月12日 下午2:55:42 * @decrition 模拟卖票线程 */ public class Ticket implements Runnable { //当前拥有的票数 private 

java中多线程通信实例:生产者消费者模式

线程间的通信: 其实就是多个线程再操作同一个资源,但是操作的动作不同   当某个线程进入synchronized块后,共享数据的状态不一定满足该线程的需要,需要其他线程改变共享数据的状态后才能运行,而由于当时线程对共享资源时独占的,它必须解除对共享资源的锁定的状态,通知其他线程可以使用该共享资源. Java中的 wait(),notify(),notifyAll()可以实现线程间的通信. 生产者--消费者问题是典型的线程同步和通信问题 /** * 生产者和消费者问题,生产者生成出产品,消费者去购

Java线程同步与死锁、生产者消费者模式以及任务调度等

一.Thread类基本信息方法 package Threadinfo; public class MyThread implements Runnable{ private boolean flag = true; private int num = 0; @Override public void run() { while(flag) { System.out.println(Thread.currentThread().getName()+"-->"+num++); } }