201521123023《Java程序设计》第11周学习总结
2017-05-06 14:22
393 查看
1. 本周学习总结
Lock、Condition,互斥同步访问方法,相比于synchronized,相似的wait()、notify()、notifyAll()方法,还有更多高级的方法Executor执行器(不需要自己创建线程,执行器负责),
将任务提交与任务如何运行解耦
以自己喜欢的方式运行任务
可以以多线程方式运行
可以直接执行其run方法(不以多线程方式运行)
子接口ExecutorService可以以线程池的方式运行
子接口ScheduledThreadPoolExecutor可以让线程按照指定时间间隔或者延迟一段时间再执行。
2. 书面作业
本次PTA作业题集多线程1.互斥访问与同步访问
完成题集4-4(互斥访问)与4-5(同步访问)1.1 除了使用synchronized修饰方法实现互斥同步访问,还有什么办法实现互斥同步访问(请出现相关代码)?
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; class Account{ private int balance; private Lock lock = new ReentrantLock(); private Condition condition = lock.newCondition(); public Account(int balance) { super(); this.balance = balance; } public int getBalance() { return balance; } public void deposit(int money){ try{ lock.lock(); this.balance=getBalance()+money; condition.signalAll(); } finally{ lock.unlock(); } } public void withdraw(int money){ try{ lock.lock(); while(getBalance()==0){ try { condition.await(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } condition.signalAll(); this.balance=getBalance()-money; } finally{ lock.unlock(); } } }
1.2 同步代码块与同步方法有何区别?
同步代码块锁定方法中的部分代码,同步方法锁定整个方法,从资源共享的合理性来看,有时我们只需要防止某一部分的资源被多个线程同时访问,如果用同步方法的话,效率上就没有同步代码块的高。1.3 实现互斥访问的原理是什么?请使用对象锁概念并结合相应的代码块进行说明。当程序执行synchronized同步代码块或者同步方法时,线程的状态是怎么变化的?
原理:当资源被访问,为其上锁,阻止其他线程访问,停止访问时,解锁,其他线程可以访问public synchronized void deposit(int money){//synchronized修饰 this.balance=getBalance()+money; notifyAll(); } public synchronized void withdraw(int money){//synchronized修饰 while(getBalance()==0){ try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.balance=getBalance()-money; notifyAll(); }
若无
synchronized修饰,可能有多个线程通过
deposit或
withdraw方法同时存取
Account对象的
balance属性。
使用
synchronized修饰后
1.线程A执行deposit,balance上锁,线程B wait,notifyAll之后,balance解锁 2.线程B执行withdraw,balance上锁,线程A无法访问,notifyAll之后,balance解锁
1.4 Java多线程中使用什么关键字实现线程之间的通信,进而实现线程的协同工作?为什么同步访问一般都要放到synchronized方法或者代码块中?
2.交替执行
2.1相关代码
import java.util.ArrayList; import java.util.Scanner; class Repo { private ArrayList<String> str = new ArrayList<String>(); private boolean flag = false; public void setFlag(boolean flag) { this.flag = flag; } public boolean isFlag() { return flag; } public ArrayList<String> getStr() { return str; } public Repo(String items) { Scanner sc = new Scanner(items); while (sc.hasNext()) { str.add(sc.next()); } sc.close(); } public int getSize() { return str.size(); } } class Worker1 implements Runnable { Repo repo; public Worker1(Repo repo) { this.repo = repo; } @Override public void run() { while (repo.getStr().size() > 0) { if (repo.isFlag()) { try { Thread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } notifyAll(); } else { System.out.println(Thread.currentThread().getName() + " finish " + repo.getStr().get(0)); repo.getStr().remove(0); repo.setFlag(true); notifyAll(); } } } } class Worker2 implements Runnable { Repo repo; public Worker2(Repo repo) { this.repo = repo; } @Override public void run() { while (repo.getStr().size() > 0) { if (!repo.isFlag()) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } notifyAll(); } else { System.out.println(Thread.currentThread().getName() + " finish " + repo.getStr().get(0)); repo.getStr().remove(0); repo.setFlag(false); notifyAll(); } } } }
2.2实验总结(不管有没有做出来)
使用ArrayList存储任务,有效保证输入的任务数能全部被录入要做到交替执行,需要中间桥梁来确认是否执行该任务,这个桥梁就是flag
3.互斥访问
3.1 修改TestUnSynchronizedThread.java源代码使其可以同步访问。(关键代码截图,需出现学号)
//201521123023 public static synchronized void addId() { id++; } public static synchronized void subtractId() { id--; }
3.2 进一步使用执行器改进相应代码(关键代码截图,需出现学号)
参考资料:Java多线程之Executor、ExecutorService、Executors、Callable、Future与FutureTask//21521123023 ExecutorService exec=Executors.newCachedThreadPool(); for(int i=0;i<6;i++){ if(i<3) exec.execute(new Adder()); else exec.execute(new Subtracter()); } exec.shutdown();
4.线程间的合作:生产者消费者问题
4.1 运行MyProducerConsumerTest.java。正常运行结果应该是仓库还剩0个货物。多运行几次,观察结果,并回答:结果正常吗?哪里不正常?为什么?
结果不正常,剩余个数从0到10皆有,因为生产者与消费者的存取速度不一致,所以会导致生产和消费不一致4.2 使用synchronized, wait, notify解决该问题(关键代码截图,需出现学号)
//201521123023 public synchronized void add(String t) { while(repo.size() == capacity) { System.out.println("仓库已满!无法添加货物。"); try { wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } repo.add(t); notifyAll(); } public synchronized void remove() { while (repo.size() == 0) { System.out.println("仓库无货!无法从仓库取货"); try { wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } repo.remove(0); notifyAll(); }
4.3 选做:使用Lock与Condition对象解决该问题。
//201521123023 private Lock lock=new ReentrantLock(); private Condition condition = lock.newCondition(); public synchronized void add(String t) { try{ lock.lock(); while(repo.size() == capacity) { System.out.println("仓库已满!无法添加货物。"); try { condition.await(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } repo.add(t); condition.signalAll(); } finally{ lock.unlock(); } } public synchronized void remove() { try{ lock.lock(); while (repo.size() == 0) { System.out.println("仓库无货!无法从仓库取货"); try { condition.await(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } repo.remove(0); condition.signalAll(); } finally{ lock.unlock(); } }
5.查询资料回答:什么是线程安全?(用自己的话与代码总结,写自己看的懂的作业)
几个人都想看电视,可电视只有一台;几个线程都想“自加(减)id”,可id只有一个;
public static void addId() { id++; } public static void subtractId() { id--; }
当一个线程addId的同时,另一个线程subtractId,这时id的值到底是啥,谁也不清楚,矛盾就产生了,线程安全问题就出现了。(“不给我看电视?我打你!!!” “我也要看!!!看打!!!”)
3. 码云上代码提交记录
3.1 码云代码提交记录
3.2截图多线程PTA提交列表
相关文章推荐
- 201521123023《Java程序设计》第10周学习总结
- 201521123121 《Java程序设计》第11周学习总结
- 201521123098 《Java程序设计》第11周学习总结
- 201521123082 《Java程序设计》第11周学习总结
- 201521123044 《Java程序设计》第11周学习总结
- 201521123001《Java程序设计》第11周学习总结
- 201521123007《Java程序设计》第11周学习总结
- 201521123036 《Java程序设计》第11周学习总结
- 201521123107 《Java程序设计》第11周学习总结
- 201521123063 《Java程序设计》 第11周学习总结
- 201521145048《Java程序设计》第11周学习总结
- 201521123002《Java程序设计》第11周学习总结
- 201521123101 《Java程序设计》第11周学习总结
- 201521123091 《Java程序设计》第11周学习总结
- 201521123023《Java程序设计》第8周学习总结
- 201521123017 《Java程序设计》第11周学习总结
- 201521123010 《Java程序设计》第11周学习总结
- 201521123006 《java程序设计》 第11周学习总结
- 201521123100 《Java程序设计》第11周学习总结
- 201521123084 《Java程序设计》第11周学习总结