201871010123- Wu Lili "object-oriented programming (Java)" Week 17 learning summary

                                                                               201871010123- Wu Lili "object-oriented programming (Java)" Week 17 learning summary

project content
This work belongs courses https://www.cnblogs.com/nwnu-daizh/
Where this requirement in the job https://www.cnblogs.com/nwnu-daizh/p/12073034.html
Job learning objectives

(1) understand and master the property and priority scheduling method thread;

(2) to grasp the concept and implementation of thread synchronization technology;

(3) Java threads comprehensive programming exercises

Part I: summary of thread synchronization technology

1, multithreaded concurrent execution,
the relative order of execution of multiple threads ➢ uncertain.

➢ thread execution order uncertainty create uncertainty in the results.

➢ In a multithreaded often create uncertainty for shared data operations.

2, thread synchronization

a) multi-threaded run concurrently uncertainties solution: the introduction of thread synchronization mechanism

b) There are two in Java multi-thread synchronization methods:

-Java SE 5.0 class introduced ReentrantLock

● ReentrantLock()

Construct can be used to protect a critical section of the reentrant lock

● ReentrantLock(boolean fair)

Construction of a lock with a fair policy. A fair lock preference longest-waiting thread. However, to ensure this fair will be greatly reduced performance. So, by default, the lock is not being forced to fair.

- plus synchronized modifier in front of the class method of shared memory.

……

public synchronized static void sub(int m)

……

(1) Solution a: lock object and target conditions

The basic structure of the protective ReentrantLock code block with the following:

myLock.lock();
try {
     critical section
}
finally
{
     myLock.unlock(); 
}

 

The key points about the lock object and condition object:

➢ to protect the lock code segments, to ensure that any time only one thread is executing code in protected.

➢ Lock Manager thread attempting to enter the protected code segment.

➢ lock may have one or more associated conditions objects .
➢ Each condition object management Those threads have entered the protected code segment but can not run.

In the critical area conditions object await (), signal (), signalAll () method to achieve interaction between threads

●void await()

The condition of the thread into the wait set.

●void signalAll()

The conditions for releasing wait concentrated blocked all threads.

●void signal()

 

Selecting a thread from a wait condition in the set of random, unblock.

➢ a thread in a critical section, may on an issue, you must use the lock object await () method to make this thread to wait temporarily give up the right to use the CPU, and allow other threads to use this synchronization method.

➢ If the thread exits the critical section, the application singal randomly select a thread unblock;

➢ If the thread exits the critical region, execution notifyAll () method notifies all waiting for this critical area due to the end of the thread waits.
(2) Solution two: synchronized keyword

the role of the synchronized keyword:

➢ a class after the synchronized method modified method is referred to as the synchronization method;

➢ As long as a thread is accessing the synchronization method, other threads want to access the synchronization method will be blocked until the thread wakes up the blocked thread synchronization method returns from the front, the other party may enter the thread synchronization method.

3, using the wait (), notify and notifyAll () in the synchronization process implemented method of interaction between threads

●void notifyAll()

Unblock those calls the wait method on the object thread. This method can only be invoked in a sync block or an internal synchronization method. If the current thread is not the object lock holder, IllegalMonitorStateException the method throws an exception.

● void notify ()
randomly selecting a call wait method on the object thread unblock. This method can only be called a synchronization method or sync blocks. If the current thread is not the object lock holder, IllegalMonitorStateException the method throws an exception.

● void wait ()
causes the thread into a wait state until it is notified. This method can only be called a synchronization method. If the current thread is not the object lock holder, the method throws eleven llegalMonitorStateException exception. Void the wait ● (Long of millis)
● void the wait (Long of millis, int nanos)
causes the thread into a wait state until it has been notified, or after a specified time. These methods can only be called a synchronization method. If the current thread is not the owner of the object lock IlalMonitorStateException method throws an exception.

Parameters: millis milliseconds

          nanos nanoseconds, <1000000

➢ a thread synchronization method used, it may be necessary problem, you must use the wait () method to make this thread to wait temporarily give up the right to use the CPU, and allow other threads to use this synchronization method.

➢ If you run out of thread synchronization method, application execution notify () method randomly selects a synchronization due to the use of this method in the waiting thread waiting for the end.

➢ If you run out of thread synchronization method, application execution notifyAl () method notifies all synchronization due to the use of this method in the waiting thread waiting for the end. Part II: Experimental part

 

Experimental seventeen thread synchronization control 

 

Experimental time 201 . 8 -12- 10

 

1 , experimental purposes and requirements

 

(1) Grasp the concept and implementation of thread synchronization technology;

 

(2) comprehensive programming practice thread

 

2 , experimental and step

 

Experiment 1: Test procedures and code comments.

 

Test Procedure 1:

 

in Elipse debugging teaching environment 651 Pager 14-7 , combined result of the program understand the program;

 

mastered the use of multithreading synchronization lock objects and conditions for realization of the object.

SynchBankTest.java code is as follows:

Synch Package; 

/ ** 
 * This program shows how to safely multithread access data structure 
 * @version 1.31 2015-06-21 
 * @author Cay Horstmann 
 * / 
public class SynchBankTest 
{ 
   public static int NACCOUNTS Final = 100; 
   public static Final Double INITIAL_BALANCE = 1000; 
   public static Final Double MAX_AMOUNT = 1000; 
   public static Final int the DELAY = 10; 
   
   public static void main (String [] args) 
   { 
      Bank Bank = new new Bank (NACCOUNTS, INITIAL_BALANCE); 
      for (int I = 0; I <NACCOUNTS; I ++) 
      { 
         int fromAccount = I; 
         // is a function of the Runnable interface, using lambda expression 
         the Runnable R & lt = () -> {  
            the try
            {
               while (true)
               {
                  int toAccount = (int) (bank.size() * Math.random());
                  double amount = MAX_AMOUNT * Math.random();
                  bank.transfer(fromAccount, toAccount, amount);
                  Thread.sleep((int) (DELAY * Math.random()));   //线程的休眠状态
               }
            }
            catch (InterruptedException e)
            {
            }            
         };
         Thread t = new Thread(r);
         t.start();
      }
   }
}

 

Bank.java code is as follows:

Synch Package Penalty for; 

Import Classes in java.util *;. 
Import java.util.concurrent.locks *;. 

/ ** 
 * Many banks have a bank account, it uses locks to serialize access 
 * @version 1.30 2004-08-01 
 * Cay Horstmann @author 
 * / 
public class Bank 
{ 
   Private Final Double [] accounts; 
   Private lock bankLock; // object locks 
   private condition sufficientFunds; // condition object 

   / ** 
    * construct bank 
    * @param number of accounts 
    * @param each the initial account balance 
    * / 
   public Bank (n-int, Double initialBalance) 
   { 
      accounts new new Double = [n-]; 
      Arrays.fill (accounts, initialBalance); 
      bankLock of ReentrantLock new new = ();
      = bankLock.newCondition sufficientFunds (); 
         Accounts [to] + = AMOUNT; 
   }

   / ** 
    * money from one account to another 
    * @param from the account 
    * @param arrival to 
    * @param amount to be transferred 
    * / 
   public void Transfer (int from, int to, Double AMOUNT) throws InterruptedException 
   { 
      bankLock.lock (); // added lock 
      the try 
      { 
         the while (Accounts [from] <AMOUNT) 
            sufficientFunds.await (); // call to await condition object method, enters the blocked state 
         System.out.print (Thread. currentThread ()); thread objects // output representative of execution threads 
         Accounts [from] - = AMOUNT; 
         System.out.printf ( "% 10.2f% from D to D%", AMOUNT, from, to); 
         the System.out .printf ( "Total Balance:% 10.2f % n", getTotalBalance ()); 
         sufficientFunds.signalAll (); // call to method conditions signalAll object unblock waiting threads 
      } 
      the finally 
      { 
         bankLock.unlock ( ); // unlock 
      } 
   } 

   / ** 
    * Get the sum of all account balances 
    * @return total balance 
    * / 
   public Double getTotalBalance () 
   { 
      bankLock.lock (); // locking 
      the try 
      { 
         Double sUM = 0; 

         for (Double A: Accounts) 
            SUM = A +; 

         return SUM; 
      } 
      the finally 
      { 
         bankLock.unlock (); // unlock 
      } 
   } 

   / ** 
    * Get Bank accounts compiled in. 
    * @return number of accounts
    */
   public int size()
   {
      return accounts.length;
   }
}

Screenshot result of the program are as follows:

 

 

Test Procedure 2 :

 

in Elipse debugging teaching environment 655 Pager 14-8 , combined result of the program understand the program;

 

Master the synchronized application of multi-thread synchronization.

Bank.java code is as follows:

 

package synch2;

import java.util.*;

/**
 * 使用同步原理的具有多个银行帐户的银行
 * @version 1.30 2004-08-01
 * @author Cay Horstmann
 */
public class Bank
{
   private final double[] accounts;

   /**
    * 构建了银行
    * @param 账户数量
    * @param 每个账户的初始余额
    */
   public Bank(int n, double initialBalance)
   {
      accounts = new double[n];
      Arrays.fill(accounts, initialBalance);
   }

   /**
    * 把钱从一个账户转到另一个账户
    * @param 从账户转出
    * @param 到账转到
    * @param 转帐金额
    */
   //类内方法用synchronized修饰后,该方法为同步方法
   public synchronized void transfer(int from, int to, double amount) throws InterruptedException
   {
      while (accounts[from] < amount)
         wait();
      System.out.print(Thread.currentThread());
      accounts[from] -= amount;
      System.out.printf(" %10.2f from %d to %d", amount, from, to);
      accounts[to] += amount;
      System.out.printf(" Total Balance: %10.2f%n", getTotalBalance());
      notifyAll();    //执行notifyAll方法通知所有由于这个同步方法而处于等待的线程结束等待
   }

   /**
    * 获取所有帐户余额的总和
    * @return the total balance
    */
   public synchronized double getTotalBalance()
   {
      double sum = 0;

      for (double a : accounts)
         sum += a;

      return sum;
   }

   /**
    * 获取银行中的帐户编号.
    * @return  账户数量
    */
   public int size()
   {
      return accounts.length;
   }
}

 

 

SynchBankTest2.java代码如下:

package synch2;

/**
 * 这个程序展示了多线程如何安全地访问一个数据结构,使用同步方法
 * @version 1.31 2015-06-21
 * @author Cay Horstmann
 */
public class SynchBankTest2
{
   public static final int NACCOUNTS = 100;
   public static final double INITIAL_BALANCE = 1000;
   public static final double MAX_AMOUNT = 1000;
   public static final int DELAY = 10;

   public static void main(String[] args)
   {
      Bank bank = new Bank(NACCOUNTS, INITIAL_BALANCE);
      for (int i = 0; i < NACCOUNTS; i++)
      {
         int fromAccount = i;
         Runnable r = () -> {
            try
            {
               while (true)
               {
                  int toAccount = (int) (bank.size() * Math.random());
                  double amount = MAX_AMOUNT * Math.random();
                  bank.transfer(fromAccount, toAccount, amount);
                  Thread.sleep((int) (DELAY * Math.random()));
               }
            }
            catch (InterruptedException e)
            {
            }
         };
         Thread t = new Thread(r);
         t.start();
      }
   }
}

 

程序运行结果截图如下:

测试程序3

 

Elipse环境下运行以下程序,结合程序运行结果分析程序存在问题;

 

尝试解决程序中存在问题。

 

class Cbank

{

     private static int s=2000;

     public   static void sub(int m)

     {

           int temp=s;

           temp=temp-m;

          try {

     Thread.sleep((int)(1000*Math.random()));

   }

           catch (InterruptedException e)  {              }

          s=temp;

          System.out.println("s="+s);

  }

}

 

 

class Customer extends Thread

{

  public void run()

  {

   for( int i=1; i<=4; i++)

     Cbank.sub(100);

    }

 }

public class Thread3

{

 public static void main(String args[])

  {

   Customer customer1 = new Customer();

   Customer customer2 = new Customer();

   customer1.start();

   customer2.start();

  }

}

 程序代码如下:

package pro;
class Cbank
	{
    private static int s=2000;
    public   static void sub(int m)
    {
          int temp=s;
          temp=temp-m;
         try {
  			  Thread.sleep((int)(1000*Math.random()));
  			}
          catch (InterruptedException e)  {              }
   	      s=temp;
   	      System.out.println("s="+s);
 		}
	}


class Customer extends Thread
{
 public void run()
 {
  for( int i=1; i<=4; i++)
    Cbank.sub(100);
   }
}
public class Thread3
{
public static void main(String args[])
 {
  Customer customer1 = new Customer();
  Customer customer2 = new Customer();
  customer1.start();
  customer2.start();
 }
}

 

运行结果截图如下:

 

 其存在问题是:这两个线程是各做各的,互不影响,它们相对执行顺序不确定,其执行顺序不确定性会产生执行结果的不确定性。

(用synchronized关键字)修改程序后代码如下:

package pro;
class Cbank
	{
    private static int s=2000;
    public synchronized static void sub(int m)
    {
          int temp=s;
          temp=temp-m;
         try {
  			  Thread.sleep((int)(1000*Math.random()));
  			}
          catch (InterruptedException e)  {              }
   	      s=temp;
   	      System.out.println("s="+s);
 		}
	}


class Customer extends Thread
{
 public void run()
 {
  for( int i=1; i<=4; i++)
    Cbank.sub(100);
   }
}
public class Thread3
{
public static void main(String args[])
 {
  Customer customer1 = new Customer();
  Customer customer2 = new Customer();
  customer1.start();
  customer2.start();
 }
}

 

程序运行结果如下截图所示:

 

实验编程练习

 

利用多线程及同步方法,编写一个程序模拟火车票售票系统,共3个窗口,卖10张票,程序输出结果类似(程序输出不唯一,可以是其他类似结果)。

 

Thread-0窗口售:第1张票

 

Thread-0窗口售:第2张票

 

Thread-1窗口售:第3张票

 

Thread-2窗口售:第4张票

 

Thread-2窗口售:第5张票

 

Thread-1窗口售:第6张票

 

Thread-0窗口售:第7张票

 

Thread-2窗口售:第8张票

 

Thread-1窗口售:第9张票

 

Thread-0窗口售:第10张票

程序设计思路:

首先创建一个售票的一个线程组,其有3个线程售票,然后通过传递sellTicketThreadGroud参数给一个新的线程,重写run方法,执行sell方法,其中sell方法是使用 synchronized 关键字来修饰的,其确保在一个时刻只有一个线程可以进入sell方法执行代码。

流程图如下:

 

 

 

 

 

 程序代码如下:

package track;
/**
 * 使用 synchronized 关键字实现线程同步的售卖火车票的测试类
 */
public class SellTickets3 {
	private static int tickets = 1; 
	
	// 使用 synchronized 关键字修饰方法,确保某一时刻只有一个线程能够进入该方法中执行代码
	protected synchronized static void sell() {
		if (tickets <= 10) {
			System.out.println(Thread.currentThread().getName() + "窗口售:第 " + tickets++ + " 张票");
		}
	}
	
	public static void startSell() {
        // 售票线程所在线程组
        ThreadGroup sellTicketThreadGroup = new ThreadGroup("sell ticket thread group");
        // 开启 3个线程售票
        for (int i = 0; i < 3; i++) {
            // 新建售票线程,并将其加入售票线程组中
            new Thread(sellTicketThreadGroup, "Thread-" + (i)) {
                @Override
                public void run() {
                    while (tickets > 0) {
                        sell();
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            // TODO 自动生成的 catch 块
                            e.printStackTrace();
                        }
                    }
                }
            }.start();
        }
        
    }


public static void main(String[] args) {
	SellTickets3.startSell();
}
}

 

运行结果截图如下:

 

实验总结:

本周学习了同步线程的相关问题,了解了并发多线程的两种解决方法,一种是锁对象,还有一种是synchronized关键字。还有在同步线程中使用wait()、notify()和notifyAll()方法,使用wait()方法使本线程等待,暂时让出CPU的使用权,并允许其它线程使用这个同步方法。线程如果用完同步方法,应当执行notifyAll()方法通知所有由于使用这个同步方法而处于等待的线程结束等待。在本周的学习中,自己对同步线程有所掌握,懂得了同步线程的基本工作原理,同时对老师所讲的理论知识有了很好的理解,在这星期中收获挺大的。

 

 

 

Guess you like

Origin www.cnblogs.com/lily-2018/p/12078367.html