我是靠谱客的博主 安静毛巾,最近开发中收集的这篇文章主要介绍传统线程同步通信synchronized,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1.典型的生产者消费者问题

    先生产再消费,A生产完后 通知B消费 B消费完后通知A 再生产 依次往复。

 

package com.yanghs.test.pro;
/**
* @author yanghs
* @Description:沟通资源
* @date 2018/3/30 23:49
*/
public class Movie {
private String pic;
/*信号灯 true生产者生产 false消费者消费*/
private boolean flag = true;
public synchronized void play(String pic) throws InterruptedException {
if(!flag){
wait();
}
this.pic = pic;
/*生产完毕 更改信号灯 为消费者*/
System.out.println("生产完毕");
this.flag = false;
this.notify();
}
public synchronized void watch() throws InterruptedException {
if(flag){
wait();
}
System.out.println(pic);
System.out.println("消费完毕");
/*t通知生产者*/
this.notify();
this.flag = true;
}
}

关键点 把生产者和消费者抽象为一个类里面 便于加锁和通信  上面是抽象好的一个类

生产者

package com.yanghs.test.pro;
/**
* @author yanghs
* @Description:生产者
* @date 2018/3/30 23:52
*/
public class Player implements Runnable {
private Movie m;
public Player(Movie m) {
this.m = m;
}
@Override
public void run() {
for(int i=0; i<=20;i++){
try {
m.play("aaaaaaaaaa");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

消费者

package com.yanghs.test.pro;
/**
* @author yanghs
* @Description:消费者
* @date 2018/3/30 23:52
*/
public class Watcher implements Runnable {
private Movie m;
public Watcher(Movie m) {
this.m = m;
}
@Override
public void run() {
for (int i=0; i<=20;i++){
try {
m.watch();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

调用者

package com.yanghs.test.pro;
/**
* @author yanghs
* @Description:
* @date 2018/3/30 23:59
*/
public class App {
public static void main(String[] args) {
Movie m = new Movie();
Player p
= new Player(m);
Watcher w = new Watcher(m);
new Thread(p).start();
new Thread(w).start();
}
}

2.一个面试题

    有主线程和子线程,要求子线程先运行5次 后 主线程运行 5次 依次往复5次

分析:子线程主线程是有运行顺序的 运行顺序可以通过 join 和 synchronized wait notify实现 但是这里又要求 这个动作要循环5次,就是  a>b>a>b... 显然join不符合。所以应该向wait这边靠。

    1)子线程和主线程需要相互通知运行 所以先抽象出逻辑代码 ab的通信,synchronized加在方法上 表示锁定调用这个方法的对象 下面的方法就表示锁定 Business实例化的对象 

对象锁是在一个类的对象上加的的锁,只有一把,不管有几个方法进行了同步。
这些同步方法都共有一把锁,只要一个线程获得了这个对象锁,其他的线程就不能访问该对象的任何一个同步方法。

class Business{
volatile boolean flag = true;//子线程运行 true
public synchronized void sub(){
if(!flag){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for(int i=0;i<=3;i++){
System.out.println("子线程"+i);
}
flag = false;
notify();
}
public
synchronized void main(){
if(flag){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for(int i=0;i<=3;i++){
System.out.println("主线程"+i);
}
flag = true;
notify();
}
}

    2)调用

public class TraSynchronized {
public static void main(String[] args) {
/*建一个业务*/
final Business b = new Business();
/*新建一个子线程 并且开启运行 业务中的sub()*/
new Thread(new Runnable() {
@Override
public void run() {
for(int i =0 ;i<=5;i++){
b.sub();
}
}
}).start();
/*主线程执行 main()*/
for(int i =0 ;i<=5;i++){
b.main();
}
}
}

实现效果






最后

以上就是安静毛巾为你收集整理的传统线程同步通信synchronized的全部内容,希望文章能够帮你解决传统线程同步通信synchronized所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部