我是靠谱客的博主 安静毛巾,这篇文章主要介绍传统线程同步通信synchronized,现在分享给大家,希望可以做个参考。

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

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

 

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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; } }

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

生产者

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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(); } } } }

消费者

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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(); } } } }

调用者

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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实例化的对象 

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

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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)调用

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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内容请搜索靠谱客的其他文章。

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

评论列表共有 0 条评论

立即
投稿
返回
顶部