Java多线程--synchronized ,Condition,BlockingQueue应用实例
2016-07-28 21:38
801 查看
//注:对文中提到的简单概念不熟悉的可自行Google或百度
创建线程有两种方法。继承Thread类或者实现runnable接口。
下面用Thread简单创建两个线程:
结果:
由于没有指定线程名字,输出的是线程的默认值Thread-n的形式,main是主线程。
考虑一个问题:
用多线程知识完成一个需求,设计一个子线程,运行10次循环后让主线程循环100次,子又循环10次,如此往复50次.
这是一个著名的多线程面试题,解答如下:
也可以使用阻塞队列BlockingQueue完成
Condition的await()方法和signal()方法类似于Object的wait()和notify()方法,也可以完成上述功能。
如果是三个线程交替呢?请看下面
创建线程有两种方法。继承Thread类或者实现runnable接口。
下面用Thread简单创建两个线程:
public class Thread1 extends Thread { public void run(){ System.out.println(this.getName()); } public static void main(String[] args) { System.out.println(Thread.currentThread().getName()); Thread1 thread1 = new Thread1(); Thread1 thread2 = new Thread1(); thread1.start(); thread2.start(); } }
结果:
main Thread-0 Thread-1
由于没有指定线程名字,输出的是线程的默认值Thread-n的形式,main是主线程。
考虑一个问题:
用多线程知识完成一个需求,设计一个子线程,运行10次循环后让主线程循环100次,子又循环10次,如此往复50次.
这是一个著名的多线程面试题,解答如下:
package SyncronizationTest; /** * Created by yangl on 2017/5/26. * 题目:用多线程知识完成一个需求,设计一个子线程,运行10次循环后让主线程循环100次,子又循环10次,如此往复50次 */ class Business{ private boolean bShouldSub = true; public synchronized void sub(){ if (!bShouldSub){//使用while更能使程序更加健壮,防止伪唤醒(下同) try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } for (int i = 0;i < 10;i++){ System.out.println("sub thread" + i); } bShouldSub = false; this.notify(); } public synchronized void main() { if (bShouldSub){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } for (int i = 0;i < 100;i++){ System.out.println("main thread :" + i); } bShouldSub = true; this.notify(); } } public class SyncronizedSwitch { public static void main(String [] args){ Business business = new Business(); new Thread(new Runnable(){ @Override public void run() { for (int i = 0; i < 50; i++) { business.sub(); } } }).start(); for (int i = 0; i < 50; i++) { business.main(); } } }
也可以使用阻塞队列BlockingQueue完成
package BlockingQueueTest; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; /** * Created by yangl on 2017/5/28. */ class Business{ BlockingQueue<Integer> blockingQueue1 = new ArrayBlockingQueue<Integer>(1);//队列中只放置一个数据 BlockingQueue<Integer> blockingQueue2 = new ArrayBlockingQueue<Integer>(1); public Business(){ try { blockingQueue2.put(1); } catch (InterruptedException e) { e.printStackTrace(); } } private boolean bShouldSub = true; public void sub(){ try { blockingQueue1.put(1); } catch (InterruptedException e) { e.printStackTrace(); } for (int i = 0;i < 10;i++){ System.out.println("sub thread: " + i); } try { blockingQueue2.take(); } catch (InterruptedException e) { e.printStackTrace(); } } public void main() { try { blockingQueue2.put(1); } catch (InterruptedException e) { e.printStackTrace(); } for (int i = 0;i < 100;i++){ System.out.println("main thread :" + i); } try { blockingQueue1.take(); } catch (InterruptedException e) { e.printStackTrace(); } } } public class BlockingQueueTest { public static void main(String [] args){ Business business = new Business(); new Thread(new Runnable(){ @Override public void run() { for (int i = 0; i < 50; i++) { business.sub(); } } }).start(); for (int i = 0; i < 50; i++) { business.main(); } } }
Condition的await()方法和signal()方法类似于Object的wait()和notify()方法,也可以完成上述功能。
package ConditionTest; /** * Created by yangl on 2017/5/28. */ import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * Created by yangl on 2017/5/26. * 题目:用多线程知识完成一个需求,设计一个子线程,运行10次循环后让主线程循环100次,子又循环10次,如此往复50次 */ class Business{ Lock lock = new ReentrantLock(); Condition condition = lock.newCondition(); private boolean bShouldSub = true; public void sub(){ lock.lock(); if (!bShouldSub){//使用while更能使程序更加健壮,防止伪唤醒 try { condition.await(); } catch (Exception e) { e.printStackTrace(); } } for (int i = 0;i < 10;i++){ System.out.println("sub thread" + i); } bShouldSub = false; condition.signal(); lock.unlock(); } public void main() { lock.lock(); if (bShouldSub){ try { condition.await(); } catch (Exception e) { e.printStackTrace(); } } for (int i = 0;i < 100;i++){ System.out.println("main thread :" + i); } bShouldSub = true; condition.signal(); lock.unlock(); } } public class ConditionTest { public static void main(String [] args){ Business business = new Business(); new Thread(new Runnable(){ @Override public void run() { for (int i = 0; i < 50; i++) { business.sub(); } } }).start(); for (int i = 0; i < 50; i++) { business.main(); } } }
如果是三个线程交替呢?请看下面
package ConditionTest; /** * Created by yangl on 2017/5/28. */ import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * Created by yangl on 2017/5/28. * 题目:用多线程知识完成一个需求,设计两个子线程sub和sub2,sub运行10次循环后让sub2运行20次,接着主线程循环100次, * sub又循环10次,sub2又循环20次...如此往复50次 */ class Business{ Lock lock = new ReentrantLock(); Condition condition = lock.newCondition(); Condition condition1 = lock.newCondition(); Condition condition2 = lock.newCondition(); //bShouldSub == 0代表main线程,1代表线程sub,2代表线程sub2 private int bShouldSub = 0; public void sub(){ lock.lock(); if (bShouldSub != 1){//使用while更能使程序更加健壮,防止伪唤醒 try { condition1.await(); } catch (Exception e) { e.printStackTrace(); } } for (int i = 0;i < 10;i++){ System.out.println("sub thread" + i); } bShouldSub = 2; condition2.signal();//通知 lock.unlock(); } public void main() { lock.lock(); if (bShouldSub != 0 ){ try { condition.await(); } catch (Exception e) { e.printStackTrace(); } } for (int i = 0;i < 100;i++){ System.out.println("main thread :" + i); } bShouldSub = 1; condition1.signal(); lock.unlock(); } public void sub2(){ lock.lock(); if (bShouldSub != 2){ try { condition2.await(); } catch (Exception e) { e.printStackTrace(); } } for (int i = 0;i < 20;i++){ System.out.println("sub2 thread" + i); } bShouldSub = 0; condition.signal(); lock.unlock(); } } public class ThreeConditionTest { public static void main(String [] args){ Business business = new Business(); new Thread(new Runnable(){ @Override public void run() { for (int i = 0; i < 50; i++) { business.sub(); } } }).start(); new Thread(new Runnable(){ @Override public void run() { for (int i = 0; i < 50; i++) { business.sub2(); } } }).start(); for (int i = 0; i < 50; i++) { business.main(); } } }
相关文章推荐
- [已解决]Could not allocate CursorWindow '' of size of size 2097152 due to error -12.
- iOS基础:UITableView简单使用
- QtQuick学习整理
- Android 播放视频UI的功耗优化 && 动态增加view小结
- 最新cocoapods安装
- UITableView方法使用
- 沙箱的UI小工具——轻量级虚拟系统
- servlet中request等中文乱码问题
- Section1:UEFI概述
- Xuitls的断点续传
- poj 2926 Requirements (曼哈顿距离)
- UE4 万能锁的一种解法
- UIButton属性详解
- Hive 的分桶 & Parquet 概念
- input文本框中value值有双引号的问题
- 高精度运算-424 integer inquiry
- 玩转iOS开发:《使用系统自定义UIActivity进行内容分享》
- 虚幻4 制作UI粒子系统插件
- easyUI前后台分页代码实现
- STL学习之路(一) deque