• 201521123056 《Java程序设计》第11周学习总结


    1. 本周学习总结

    1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容。


    2. 书面作业

    本次PTA作业题集多线程


    1. 互斥访问与同步访问
    完成题集4-4(互斥访问)与4-5(同步访问)
    1.1 除了使用synchronized修饰方法实现互斥同步访问,还有什么办法实现互斥同步访问(请出现相关代码)?
    1.2 同步代码块与同步方法有何区别?
    1.3 实现互斥访问的原理是什么?请使用对象锁概念并结合相应的代码块进行说明。当程序执行synchronized同步代码块或者同步方法时,线程的状态是怎么变化的?
    1.4 Java多线程中使用什么关键字实现线程之间的通信,进而实现线程的协同工作?为什么同步访问一般都要放到synchronized方法或者代码块中?


    1.1 答:代码如下:

    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();
    synchronized void deposit(int money){
    	lock.lock();
    	try {
    		this.balance += money;
    		condition.signal();
    	} catch (IllegalMonitorStateException e) {
    		// TODO: handle exception
    	}
    	finally{
    		lock.unlock();
    	}
    }
    synchronized void withdraw(int money){
    	lock.lock();
    	try{
    		while (this.balance - money < 0) {
    			try {
    				condition.await();
    			} catch (InterruptedException e) {
    				System.out.println(e);
    			}
    		}
    		this.balance -= money;
    		condition.signal();
    	}catch (Exception e){}
    	finally{
    		lock.unlock();
    	}
    }
    

    1.2 答:区别:
    (1)同步方法:因为java的每个对象都有一个内置锁,内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态。
    (2)同步代码块:被该关键字修饰的语句块会自动被加上内置锁,从而实现同步
    (3)相比于同步方法的话,同步代码块更加高效一些。

    1.3 答:在某个时刻内只能有一个线程获得一个资源的锁,获得锁后即可访问资源,但是其他线程就得等该资源被解锁后才可获得这个锁。
    如:

    class Counter {
    	//我是201521123056
    	private static int id = 0;
    	public static  void addId() {
    		synchronized (Counter.class) {
    			id++;
    		}
    	}
    	public static synchronized void subtractId() {
    		id--;
    	}
    	public static int getId() {
    		return id;
    	}
    }
    线程的状态变化:
    (1) t1获得id的锁,然后读取id的值,此时t2等待;
    (2) t1将所取的id值+1;
    (3) t1将运算后的值再赋值给id,id的锁被解锁资源释放;
    (4) t2获得id的锁,然后读取id的值,此时t1等待;
    (5) t2将所取的id值-1;
    (6) t2将运算后的值再赋值给id,id的锁被解锁资源释放;
    

    1.4 答:(1) 可以使用wait () 和notify()/notifyAll()方法或者Condition对象来实现线程之间的通信。
    (2) 同步访问放到synchronized方法或者代码块中,是为了防止多个线程访问同一资源而引起冲突。


    2. 交替执行
    实验总结(不管有没有做出来)


    实验总结:
    (1)建立了3个类:Repo、Worker1和Worker2。Worker类实现Runnable;
    (2)在Repo类的构造函数中将字符串分解存储的方法有多个;较为实用的就是调用已知方法split(" ")将字符串分解存入数组;
    (3)在两个Worker类中覆盖了run方法,两个run方法的循环条件是getSize()!=0。


    3. 互斥访问
    3.1 修改TestUnSynchronizedThread.java源代码使其可以同步访问。(关键代码截图,需出现学号)
    3.2 进一步使用执行器改进相应代码(关键代码截图,需出现学号)
    参考资料:Java多线程之Executor、ExecutorService、Executors、Callable、Future与FutureTask


    3.1 截图如下:

    运行结果:

    3.2 截图如下:

    运行结果:


    4. 线程间的合作:生产者消费者问题
    4.1 运行MyProducerConsumerTest.java。正常运行结果应该是仓库还剩0个货物。多运行几次,观察结果,并回答:结果正常吗?哪里不正常?为什么?
    4.2 使用synchronized, wait, notify解决该问题(关键代码截图,需出现学号)
    4.3 选做:使用Lock与Condition对象解决该问题。


    4.1 答:多次运行代码发现运行结果不正常。每次运行的结果都是不确定的如下图:

    原因:是Producer和Consumer的速度不一致,所以可能导致仓库所剩货物不为0,或是资源浪费的情况。

    4.2 截图如下(出现了一个情况:第一次运行结果正常,但是之后的运行就停在放入100个货物完毕!不能够继续下去):


    5. 查询资料回答:什么是线程安全?(用自己的话与代码总结,写自己看的懂的作业)


    参考资料

    答:当你的代码所在的进程中有多个线程同时运行,这段代码可能被多个线程运行,线程安全通过线程同步控制来实现的。方法可以使用synchronized关键字,就可以确保一次只能有一个线程在访问共享资源,而不是多个线程同时访问共享资源,这样就可以避免多个线程共同使用共享资源。


    3. 码云上代码提交记录

    题目集:多线程(4-4到4-10)

    3.1. 码云代码提交记录



    3.2 截图多线程PTA提交列表



  • 相关阅读:
    C#小常识集锦(一)《更锋利的CSharp代码》读书笔记
    QueryBuilder 优雅的Linq To SQL动态查询(转)
    了解 NoSQL 的必读资料
    微软报表
    linq to sql 中,如何解决多条件查询问题,答案,用表达式树! (下)
    LINQ体验(17)——LINQ to SQL语句之动态查询
    细数那些运行在微软平台上的NoSQL数据库
    5道经典的程序题
    打造自己的LINQ Provider(中):IQueryable和IQueryProvider (转 李会军)
    Expression Examples :Report Builder
  • 原文地址:https://www.cnblogs.com/wjt960310/p/6817537.html
Copyright © 2020-2023  润新知