互联网面试总结(一) : 程序题

来源:互联网 发布:淘宝女童装品牌 编辑:程序博客网 时间:2024/06/05 17:25

多线程

1.如何用多线程去控制炸弹每隔2秒,4秒交替爆炸?(参考张孝祥)

import java.util.Date;import java.util.Timer;import java.util.TimerTask;public class TimerThread {static int count = 0;public static void main(String[] args) {// 如何用多线程去控制炸弹每隔2秒,4秒交替爆炸class CustomizedTimerTask extends TimerTask {@Overridepublic void run() {// count是奇数时为0,偶数时为1count = (++count) % 2;System.out.println("Bomb!!!!,count="+count);// count为0时,2秒触发,为1时,4秒触发,每次触发都会将count的值变为0new Timer().schedule(new CustomizedTimerTask(), 2000 + 2000 * count);}}//每2秒触发一次,每次触发都会将count的值变为1new Timer().schedule(new CustomizedTimerTask(), 2000);//打印相隔时间,可省略while (true) {System.out.println(new Date().getSeconds());try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}

执行结构:


2.子线程打印10次,主线程打印100次,如此循环50次(参考张孝祥)



3.在多线程运行时,实现多个模块在同一线程内共享数据,另外一条线程又共享另一份数据(参考张孝祥)

分析:每个线程调用全局ThreadLocal对象的set方法,就相当于往其内部的map中增加一条记录,key分别是各自的线程,value是各自的set方法传进去的值。在线程结束时可以调用ThreadLocal.clear()方法,这样会更快释放内存,不调用也可以,因为线程结束后也可以自动释放相关的ThreadLocal变量。ThreadLocal的应用场景:订单处理包含一系列操作:减少库存量、增加一条流水台账、修改总账,这几个操作要在同一个事务中完成,通常也即同一个线程中进行处理,如果累加公司应收款的操作失败了,则应该把前面的操作回滚,否则,提交所有操作,这要求这些操作使用相同的数据库连接对象,而这些操作的代码分别位于不同的模块类中。 银行转账包含一系列操作: 把转出帐户的余额减少,把转入帐户的余额增加,这两个操作要在同一个事务中完成,它们必须使用相同的数据库连接对象,转入和转出操作的代码分别是两个不同的帐户对象的方法。例如Strut2的ActionContext,同一段代码被不同的线程调用运行时,该代码操作的数据是每个线程各自的状态和数据,对于不同的线程来说,getContext方法拿到的对象都不相同,对同一个线程来说,不管调用getContext方法多少次和在哪个模块中getContext方法,拿到的都是同一个。实验案例:定义一个全局共享的ThreadLocal变量,然后启动多个线程向该ThreadLocal变量中存储一个随机值,接着各个线程调用另外其他多个类的方法,这多个类的方法中读取这个ThreadLocal变量的值,就可以看到多个类在同一个线程中共享同一份数据。实现对ThreadLocal变量的封装,让外界不要直接操作ThreadLocal变量。对基本类型的数据的封装,这种应用相对很少见。对对象类型的数据的封装,比较常见,即让某个类针对不同线程分别创建一个独立的实例对象。总结:一个ThreadLocal代表一个变量,故其中里只能放一个数据,你有两个变量都要线程范围内共享,则要定义两个ThreadLocal对象。如果有一个百个变量要线程共享呢?那请先定义一个对象来装这一百个变量,然后在ThreadLocal中存储这一个对象。


package com.evanshare;import java.util.Random;public class ThreadlocalTest {public static void main(String[] args) {for (int i = 0; i < 10; i++) {new Thread(new Runnable() {@Overridepublic void run() {// 绑定数据到当前线程ThreadLocalData.getThreadLocalData().setData(new Random().nextInt());System.out.println("线程:" + Thread.currentThread().getName() + ": has put data:"+ ThreadLocalData.getThreadLocalData().getData());// 多线程时,从A和B各自取出数据,如果同一条线程,put进去的数据和get的数据一致,则是正确new A().get();new B().get();}}).start();;}}// 把线程共享的变量和操作方法都封装在同一类中,方便维护static class ThreadLocalData {private Integer data = 0;// 给线程共享的数据对外提供一个改变数值的方法public void setData(Integer data) {this.data = data;}// 获取线程共享的数据public Integer getData() {return this.data;}// 构造方法私有化,只在内部创建对象private ThreadLocalData() {}private static ThreadLocal<Object> instanceContainer = new ThreadLocal<Object>();public static ThreadLocalData getThreadLocalData() {// 从threadLocal中取出绑定的对象ThreadLocalData threaLocalData = (ThreadLocalData) instanceContainer.get();//先判断当前实例是否存在,不存在则创建一个新的实例if (threaLocalData == null) {threaLocalData = new ThreadLocalData();// 绑定 对象到trreaLocal中,使每条线程都有自己对应的线程内独立的共享数据instanceContainer.set(threaLocalData);}return threaLocalData;}}// 其他模块static class A {public void get() {System.out.println("当前线程:" + Thread.currentThread().getName() + ":A==>data:"+ ThreadLocalData.getThreadLocalData().getData());}}// 其他模块static class B {public void get() {System.out.println("当前线程:" + Thread.currentThread().getName() + ":B==>data:"+ ThreadLocalData.getThreadLocalData().getData());}}}

执行结果:
线程:Thread-4: has put data:299256607线程:Thread-0: has put data:356189664线程:Thread-7: has put data:-1215289985线程:Thread-1: has put data:1718461731线程:Thread-6: has put data:1213215847线程:Thread-5: has put data:1144437339线程:Thread-2: has put data:-1851721218线程:Thread-8: has put data:1182402488线程:Thread-3: has put data:2050229878线程:Thread-9: has put data:-401592787当前线程:Thread-4:A==>data:299256607当前线程:Thread-5:A==>data:1144437339当前线程:Thread-2:A==>data:-1851721218当前线程:Thread-8:A==>data:1182402488当前线程:Thread-9:A==>data:-401592787当前线程:Thread-3:A==>data:2050229878当前线程:Thread-0:A==>data:356189664当前线程:Thread-7:A==>data:-1215289985当前线程:Thread-6:A==>data:1213215847当前线程:Thread-1:A==>data:1718461731当前线程:Thread-4:B==>data:299256607当前线程:Thread-0:B==>data:356189664当前线程:Thread-2:B==>data:-1851721218当前线程:Thread-7:B==>data:-1215289985当前线程:Thread-6:B==>data:1213215847当前线程:Thread-1:B==>data:1718461731当前线程:Thread-5:B==>data:1144437339当前线程:Thread-8:B==>data:1182402488当前线程:Thread-9:B==>data:-401592787当前线程:Thread-3:B==>data:2050229878



0 0