- 浏览: 864303 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (509)
- android (55)
- CSS (23)
- eclipse (25)
- Data Structes and Algorithms (53)
- J2SE (87)
- Java_面试学习_j2se (26)
- java_面试学习_非技术 (13)
- java_gui (2)
- java_设计模式 (27)
- JDBC (10)
- java_web (15)
- hibernate (5)
- Oracle (37)
- Struts2 (7)
- Word-----dos (24)
- Jbpm (3)
- java小技巧 (8)
- math (1)
- flex (12)
- WebService (4)
- 生活 (9)
- 小框架或小语言 (27)
- spring (1)
- 面试~~~软实力 (7)
- jstat的用法 (1)
- jmap (1)
- 数据链路层和传输层的流量控制区别 (1)
- shell (0)
- 财商 (1)
- javascript (0)
- js研究 (1)
- 代码收集 (0)
最新评论
-
海尔群:
http://jingyan.baidu.com/articl ...
android加密 -
完美天龙:
------------------------- ...
asm----字节码操纵 -
houniao1990:
大神,请问 string 类型 定义为 oracle的 cha ...
hibernate注解 -
JamesQian:
Line:103
f.doFilter(msg);
是否需 ...
责任链模式_过滤器模式 -
sacoole:
好评
interview--- 如何从N个数中选出最大(小)的n个数?
有两个线程,线程a先打印100下,然后线程b打印十下,然后再a打印。。。。
思路:一定要做到线程和任务分离,把a线程的任务和b线程的任务放到一个类里面来,然后再让这两个线程分别调用这个类就可以了
如果是三个交替的弄,则可以使用下面的方法,使用wait和notify,那么一共只有一个等待区,如果是使用condition,那么会明确多个等待区,这样不会唤醒不该被唤醒的线程
阻塞队列
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
以上的需求是,多个线程 在某个时刻只能有一个线程进入 其中的一个方法,也就是取东西和放东西 只能有一个操作
下面展示,某一个方法可以同时被多个线程调用,而另一个方法只能被一个线程调用。。生产者消费者问题
如果要对等待区进行的数量进行控制,则可以使用CountDownLatch
CyclicBarrier 自己的实现,CyclicBarrier就是控制缓冲区中的数目,到了一定的数目才唤醒,await里面会有计数器,当计数器到达指定值则调用notifyAll
思路:一定要做到线程和任务分离,把a线程的任务和b线程的任务放到一个类里面来,然后再让这两个线程分别调用这个类就可以了
package cn.itcast.heima2; public class TraditionalThreadCommunication { /** * @param args */ public static void main(String[] args) { final Business business = new Business(); new Thread( new Runnable() { @Override public void run() { for(int i=1;i<=50;i++){ business.sub(i); } } } ).start(); for(int i=1;i<=50;i++){ business.main(i); } } } class Business { private String executeMethodName ="sub"; public synchronized void sub(int i){ while(!executeMethodName.equals("sub")){//如果不该我执行 try { this.wait();//如果不该我执行 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } for(int j=1;j<=10;j++){ System.out.println("sub thread sequence of " + j + ",loop of " + i); } executeMethodName = "main"; this.notify(); } public synchronized void main(int i){ while(!executeMethodName.equals("main")){//如果不该我执行 try { this.wait(); //我就等等 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } for(int j=1;j<=100;j++){ System.out.println("main thread sequence of " + j + ",loop of " + i); } //令牌标示成sub,并去叫醒sub executeMethodName = "sub"; this.notify(); } }
如果是三个交替的弄,则可以使用下面的方法,使用wait和notify,那么一共只有一个等待区,如果是使用condition,那么会明确多个等待区,这样不会唤醒不该被唤醒的线程
package cn.itcast.heima2; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class ThreeConditionCommunication { /** * @param args */ public static void main(String[] args) { final Business business = new Business(); new Thread( new Runnable() { @Override public void run() { for(int i=1;i<=50;i++){ business.sub2(i); } } } ).start(); new Thread( new Runnable() { @Override public void run() { for(int i=1;i<=50;i++){ business.sub3(i); } } } ).start(); for(int i=1;i<=50;i++){ business.main(i); } } static class Business { Lock lock = new ReentrantLock(); Condition conditionMain = lock.newCondition(); Condition conditionSub2 = lock.newCondition(); Condition conditionSub3 = lock.newCondition(); private String executeMethodName = "main"; public void sub2(int i){ lock.lock(); //所只能保证只有一个人能进来,但是不能保证进来的人是谁 try{ while(!executeMethodName.equals("sub2")){//虽然我抢到了锁,但是如果不是我执行,我还是得等待 try { conditionSub2.await();//我到2区等待 } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } for(int j=1;j<=10;j++){ System.out.println("sub2 thread sequence of " + j + ",loop of " + i); } executeMethodName="sub3"; conditionSub3.signal(); }finally{ lock.unlock(); } } public void sub3(int i){ lock.lock(); try{ while(!executeMethodName.equals("sub3")){ try { conditionSub3.await(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } for(int j=1;j<=20;j++){ System.out.println("sub3 thread sequence of " + j + ",loop of " + i); } executeMethodName="main"; conditionMain.signal(); }finally{ lock.unlock(); } } public void main(int i){ lock.lock(); try{ while(!executeMethodName.equals("main")){ try { conditionMain.await(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } for(int j=1;j<=100;j++){ System.out.println("main thread sequence of " + j + ",loop of " + i); } executeMethodName = "sub2"; conditionSub2.signal(); }finally{ lock.unlock(); } } } }
阻塞队列
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; class BoundedBuffer {//阻塞队列 final Lock lock = new ReentrantLock(); final Condition puterWaitArea = lock.newCondition(); //放入者等候区 final Condition takerWaitArea = lock.newCondition(); //消费者等候区 final Object[] items = new Object[100]; //队列 int putptr, takeptr, count; public void put(Object x) throws InterruptedException { lock.lock();//一次只能一个线程进入 try { while (count == items.length) //线程进入后,查看准入条件 puterWaitArea.await(); items[putptr] = x; if (++putptr == items.length) putptr = 0; ++count;//转入条件变化 takerWaitArea.signal(); } finally { lock.unlock(); } } public Object take() throws InterruptedException { lock.lock(); try { while (count == 0)//线程进入后,查看准入条件 takerWaitArea.await(); Object x = items[takeptr]; if (++takeptr == items.length) takeptr = 0; --count; puterWaitArea.signal(); return x; } finally { lock.unlock(); } } }
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
以上的需求是,多个线程 在某个时刻只能有一个线程进入 其中的一个方法,也就是取东西和放东西 只能有一个操作
下面展示,某一个方法可以同时被多个线程调用,而另一个方法只能被一个线程调用。。生产者消费者问题
package cn.itcast.heima2; import java.util.Random; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; public class ReadWriteLockTest { public static void main(String[] args) { final Queue3 q3 = new Queue3(); for(int i=0;i<3;i++) { new Thread(){ public void run(){ while(true){ q3.get(); } } }.start(); new Thread(){ public void run(){ while(true){ q3.put(new Random().nextInt(10000)); } } }.start(); } } } class Queue3{ private Object data = null;//共享数据,只能有一个线程能写该数据,但可以有多个线程同时读该数据。 ReadWriteLock rwl = new ReentrantReadWriteLock(); public void get(){ rwl.readLock().lock();//只有一个准入条件 try { System.out.println(Thread.currentThread().getName() + " be ready to read data!"); Thread.sleep((long)(Math.random()*1000)); System.out.println(Thread.currentThread().getName() + "have read data :" + data); } catch (InterruptedException e) { e.printStackTrace(); }finally{ rwl.readLock().unlock(); } } public void put(Object data){ rwl.writeLock().lock(); try { System.out.println(Thread.currentThread().getName() + " be ready to write data!"); Thread.sleep((long)(Math.random()*1000)); this.data = data; System.out.println(Thread.currentThread().getName() + " have write data: " + data); } catch (InterruptedException e) { e.printStackTrace(); }finally{ rwl.writeLock().unlock(); } } }
private ReadWriteLock rwl = new ReentrantReadWriteLock(); public Object getData(String key){ rwl.readLock().lock(); Object value = null; try{ value = cache.get(key); if(value == null){ //如果没读到,释放读锁,加写锁 rwl.readLock().unlock(); rwl.writeLock().lock(); try{ value = cache.get(key); if(value==null){ // 防止重复写,只有value为空的时候才能写, //比如有两个线程到了rwl.writeLock().lock();,第一个线程先拿到写锁,写完后,第二个线程就不应该去写了,所以这里对第二个线程要验证下 value = "aaaa";//实际失去queryDB(); cache.put(key, value); } }finally{ rwl.writeLock().unlock(); } rwl.readLock().lock(); } }finally{ rwl.readLock().unlock(); } return value; }
如果要对等待区进行的数量进行控制,则可以使用CountDownLatch
package cn.itcast.heima2; import java.util.concurrent.CountDownLatch; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class CountdownLatchTest { public static void main(String[] args) { ExecutorService service = Executors.newCachedThreadPool(); final CountDownLatch cdOrder = new CountDownLatch(1); final CountDownLatch cdAnswer = new CountDownLatch(3); for(int i=0;i<3;i++){ Runnable runnable = new Runnable(){ public void run(){ try { System.out.println("线程" + Thread.currentThread().getName() + "正准备接受命令"); cdOrder.await(); System.out.println("线程" + Thread.currentThread().getName() + "已接受命令"); Thread.sleep((long)(Math.random()*10000)); System.out.println("线程" + Thread.currentThread().getName() + "回应命令处理结果"); cdAnswer.countDown(); } catch (Exception e) { e.printStackTrace(); } } }; service.execute(runnable); } try { Thread.sleep((long)(Math.random()*10000)); System.out.println("线程" + Thread.currentThread().getName() + "即将发布命令"); cdOrder.countDown();//这个方法里面有唤醒代码,先把数字减一,如果数字为0则唤醒线程,这相当于对notify的封装,条件被封装到了countDown方法里面,有条件的唤醒 System.out.println("线程" + Thread.currentThread().getName() + "已发送命令,正在等待结果"); cdAnswer.await(); System.out.println("线程" + Thread.currentThread().getName() + "已收到所有响应结果"); } catch (Exception e) { e.printStackTrace(); } service.shutdown(); } }
CyclicBarrier 自己的实现,CyclicBarrier就是控制缓冲区中的数目,到了一定的数目才唤醒,await里面会有计数器,当计数器到达指定值则调用notifyAll
package cn.itcast.heima2; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class CyclicBarrierTest { public static void main(String[] args) { test(); } static int count=0; static int step = 1; public static void test(){ ExecutorService service = Executors.newCachedThreadPool(); final Lock lock = new ReentrantLock(); final Condition con = lock.newCondition(); for(int i=0;i<3;i++){ Runnable runnable = new Runnable(){ public void run(){ lock.lock(); try { if(step==1){ System.out.println("线程" + Thread.currentThread().getName() + "即将到达集合地点1,当前已有" + (count+1) + "个已经到达," + (count==2?"都到齐了,继续走啊":"正在等候")); count++; if(count<3) con.await(); else{ count =0 ; step =2; con.signalAll(); } } if(step==2){ System.out.println("线程" + Thread.currentThread().getName() + "即将到达集合地点2,当前已有" + (count+1) + "个已经到达," + (count==2?"都到齐了,继续走啊":"正在等候")); count++; if(count<3) con.await(); else{ count =0 ; step =3; con.signalAll(); } } if(step==3){ System.out.println("线程" + Thread.currentThread().getName() + "即将到达集合地点3,当前已有" + (count+1) + "个已经到达," + (count==2?"都到齐了,继续走啊":"正在等候")); count++; if(count<3) con.await(); else{ count =0 ; step =4; con.signalAll(); } } lock.unlock(); } catch (Exception e) { e.printStackTrace(); } } }; service.execute(runnable); } service.shutdown(); } }
发表评论
-
多线程操作---线程取消运行
2012-06-03 18:51 0new Thread(new Runnable() { ... -
多线程操作---线程间通信封装
2012-06-03 18:34 1515Future是线程与线程间通信的封装 相当于省去了一个公共的共 ... -
多线程操作----缓存
2012-06-03 17:16 4112private Map<String,String& ... -
多线程操作----找错误
2012-06-03 16:26 1078找找下面错误 class ListHepler{ p ... -
多线程操作---可重入锁概念
2012-06-03 15:04 5212//可重入锁的概念是 自己可以再次获得自己的内部锁, //重进 ... -
setter方法提取---使用反射获得setter方法
2012-05-28 18:47 2996setters = new HashMap<S ... -
int数组转数字
2012-05-23 16:03 1219//把正数当成负数来弄,避免逼近正数maxvalue产生的 ... -
数组构造类哈希表
2012-05-23 15:15 1108private final static int[] di ...
相关推荐
一个java 多线程操作数据库应用程序!!!
易语言多线程操作源码,多线程操作,子程序1
总结了一下Qt中sqlite多线程操作遇到的几个问题,希望能对有需要的朋友一点帮助 总结了一下Qt中sqlite多线程操作遇到的几个问题,希望能对有需要的朋友一点帮助
此文档提供了一个委托方法,来控制访问listbox,用于多线程操作。c#
易语言多线程操作模块源码,多线程操作模块,时间_现行时间,互斥锁创建,互斥锁销毁,互斥锁锁定,互斥锁解锁,互斥锁异步锁定,线程启动,线程启动多参,线程创建扩展,线程销毁,线程退出,线程等待,线程强制结束,线程键创建,...
关于winform使用timer进行多线程操作的例子 一个关于网段ping的例子 很好的解释了system.timers.timer的用法
安全的多线程操作,是VB多线程的不错的选择
多线程操作数据库,可解决已加密或者比较复杂的数据库查询时间比较长的问题
之前操作sqlite一直用sdk中的SQLiteOpenHelper,在多线程操作数据库(特别是插入数据)的时候,总是提示sqlite已经被锁定,其它线程就无法继续了。 今天研究了一下android用jdbc操作sqlite,再用多线程去操作数据库的...
多线程操作窗口源码 功能介绍: 多线程是一种提高程序运行效率和性能的常用技术。 随着我们学习工作的深入,在编程中或多或少会涉及到 需要多线程的情况。多数时候,我们的操作模式是后台 线程中处理数据,计算...
10个VC 多线程操作实例源代码,基本上包含了多线程的方方面面,分别是: 如何安全终止线程 如何创建UI线程 如何创建Worker线程 如何等待线程结束 如何挂起和恢复线程 如何获得线程的退出码 如何使用互斥量 如何使用...
按键精灵经典多线程操作,可以套用于任意的其他脚本上
面试题c++mysql多线程操作系统 面试题c++mysql多线程操作系统 面试题c++mysql多线程操作系统 面试题c++mysql多线程操作系统 面试题c++mysql多线程操作系统
多线程操作窗口源码 功能介绍: 多线程是一种提高程序运行效率和性能的常用技术。 随着我们学习工作的深入,在编程中或多或少会涉及到 需要多线程的情况。多数时候,我们的操作模式是后台 线程中处理数据,计算...
适合初学者的QT多线程操作的例子 适合初学者的QT多线程操作的例子
多线程的好处在于可以提高CPU的利用率——任何一个程序员都不希望自己的程序很多时候没事可干,在多线程程序中,一个线程必须等待的时候,CPU可以运行其它的线程而不是等待,这样就大大提高了程序的效率。...
多线程操作实例源码 Windows是一个多任务的系统,如果你使用的是windows 2000及其以上版本,你可以通过任务管理器查看当前系统运行的程序和进程。什么是进程呢?当一个程序开始运行时,它就是一个进程,进程所指...
Android 多线程开发实例,对使用多线程的用户有一定的参考价值!
[开源]多线程操作模块,包括锁和线程池(非IOCP)[重要].e