zoukankan      html  css  js  c++  java
  • 孔维滢 20171010110《面向对象程序设计(java)》第十七周学习总结

    理论知识部分:

    1.程序与进程:

        程序是一段静态的代码,它是应用程序执行的蓝本。

        进程是程序的一次动态执行,它对应了从代码加载、执行至执行完毕的一个完整过程。

    2.多线程

        多线程是进程执行过程中产生的多条执行线索。

    3.进程:

        线程是比进程执行更小的单位。线程不能独立存在,必须存在于进程中,同一进程的各线程间共享进程空间的数据。每个线程有它自身的产生、存在和消亡的过程, 是一个动态的概念。线程创建、销毁和切换的负荷远小于进程,又称 为轻量级进程(lightweight process)。

    4.Java实现多线程:

        -创建Thread类的子类

        -在程序中定义实现Runnable接口的类

    5.用Thread类的子类创建线程:

        首先需从Thread类派生出一个子类,在该子类中 重写run()方法。

            class hand extends Thread { public void run() {……} }

        然后用创建该子类的对象

            Lefthand left=new Lefthand();

            Righthand right=new Righthand();

        最后用start()方法启动线程

            left.start();

            right.start();

    6.用Runnable()接口实现线程

        首先设计一个实现Runnable接口的类;

        然后在类中根据需要重写run方法;

        再创建该类对象,以此对象为参数建立Thread 类的对象;

        调用Thread类对象的start方法启动线程,将 CPU执行权转交到run方法。

    7.线程的终止

        调用interrupt()方法;

    8.

    8、测试线程是否被中断的方法

    Java提供了几个用于测试线程是否被中断的方法。

    -static boolean interrupted()

    – 检测当前线程是否已被中断 ,并重置状态 “interrupted”值为false。 

    -boolean isInterrupted()

    – 检测当前线程是否已被中断 ,不改变状态 “interrupted”值 。

    9、线程的状态

        -利用各线程的状态变换,可以控制各个线程轮流使用CPU,体现多线程的并行性特征。 

        -线程有如下7种状态:

             New (新建)

        Runnable (可运行)

        Running(运行)

        Blocked (被阻塞)

        Waiting (等待)

        Timed waiting (计时等待) 

        Terminated (被终止)

    10、新创建线程

        -new(新建)

            线程对象刚刚创建,还没有启动,此时线程还处于不可运行状态。例如: Thread thread=new Thread(r); 此时线程thread处于新建状态,有了相应的内存空间以及其它资源。

    11、可运行线程

       - runnable(可运行状态)

             此时线程已经启动,处于线程的run()方法之中。

             此时的线程可能运行,也可能不运行,只要 CPU一空闲,马上就会运行。

             调用线程的start()方法可使线程处于“可运行”状态。例如: thread.start();

    12、被阻塞线程和等待线程

        - blocked (被阻塞)

             一个正在执行的线程因特殊原因,被暂停执行, 进入阻塞状态。

            阻塞时线程不能进入队列排队,必须等到引起阻塞的原因消除,才可重新进入排队队列。

            引起阻塞的原因很多,不同原因要用不同的方法解除。

        -sleep(),wait()是两个常用引起线程阻塞的方法。

    13、线程阻塞的三种情况

        - 等待阻塞 -- 通过调用线程的wait()方法,让线程等待某工作的完成。

        - 同步阻塞 -- 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态。

        -其他阻塞 -- 通过调用线程的sleep()或join() 或发出了I/O请求时,线程会进入到阻塞状态。当 sleep()状态超时、join()等待线程终止或者超 时、或者I/O处理完毕时,线程重新转入就绪状态。

    14、被终止的线程

        Terminated (被终止) 线程被终止的原因有二:

            一是run()方法中最后一个语句执行完毕而自然死亡。

            二是因为一个没有捕获的异常终止了run方法而意外死亡。

             可以调用线程的 stop 方 法 杀 死 一 个 线 程(thread.stop();),但是,stop方法已过时, 不要在自己的代码中调用它。

    15、多线程调度

        -Java 的线程调度采用优先级策略:

             优先级高的先执行,优先级低的后执行;

            多线程系统会自动为每个线程分配一个优先级,缺省时,继承其父类的优先级;

            任务紧急的线程,其优先级较高;

            同优先级的线程按“先进先出”的队列原则;

    实验部分:

    实验1:

    测试程序1:

    package synch;
    
    /**
     * 这个程序展示了多线程如何安全地访问数据结构。
     * @version 1.31 2015-06-21
     * @author Cay Horstmann
     */
    public class SynchBankTest
    {
       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();
          }
       }
    }
    

      

    package synch;
    
    import java.util.*;
    import java.util.concurrent.locks.*;
    
    /**
     * 具有许多银行帐户的银行,使用锁序列化访问。
     * @version 1.30 2004-08-01
     * @author Cay Horstmann
     */
    public class Bank
    {
       private final double[] accounts;
       private Lock bankLock;//锁对象
       private Condition sufficientFunds;
    
       /**
        * 构建银行。
        * @param n账户数量
        * @param 每个帐户的初始余额
        */
       public Bank(int n, double initialBalance)
       {
          accounts = new double[n];
          Arrays.fill(accounts, initialBalance);
          bankLock = new ReentrantLock();
          sufficientFunds = bankLock.newCondition();
       }
    
       /**
        * 把钱从一个账户转到另一个账户,再从一个账户转到另一个账户,再从另一个账户转到另一个账户
        * @param from the account to transfer from
        * @param to the account to transfer to
        * @param amount the amount to transfer
        */
       public void transfer(int from, int to, double amount) throws InterruptedException
       {
          bankLock.lock();
          try
          {//锁对象的引用条件对象
             while (accounts[from] < amount)
                sufficientFunds.await();
             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());
             sufficientFunds.signalAll();
          }
          finally
          {
             bankLock.unlock();
          }
       }
    
       /**
        * 获取所有帐户余额的总和。
        * @return 总平衡
        */
       public double getTotalBalance()
       {
          bankLock.lock();//加锁
          try
          {
             double sum = 0;
    
             for (double a : accounts)
                sum += a;
    
             return sum;
          }
          finally
          {
             bankLock.unlock();//解锁
          }
       }
    
       /**
        * 获取银行中的帐户数量。
        * @return 账户数量
        */
       public int size()
       {
          return accounts.length;
       }
    }
    

      

    package synch2;
    
    import java.util.*;
    
    /**
     * A bank with a number of bank accounts that uses synchronization primitives.
     * @version 1.30 2004-08-01
     * @author Cay Horstmann
     */
    public class Bank
    {
       private final double[] accounts;
    
       /**
        * Constructs the bank.
        * @param n the number of accounts
        * @param initialBalance the initial balance for each account
        */
       public Bank(int n, double initialBalance)
       {
          accounts = new double[n];
          Arrays.fill(accounts, initialBalance);
       }
    
       /**
        * Transfers money from one account to another.
        * @param from the account to transfer from
        * @param to the account to transfer to
        * @param amount the amount to transfer
        */
       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();
       }
    
       /**
        * Gets the sum of all account balances.
        * @return the total balance
        */
       public synchronized double getTotalBalance()
       {
          double sum = 0;
    
          for (double a : accounts)
             sum += a;
    
          return sum;
       }
    
       /**
        * Gets the number of accounts in the bank.
        * @return the number of accounts
        */
       public int size()
       {
          return accounts.length;
       }
    }
    

      

    package synch2;
    
    /**
     * This program shows how multiple threads can safely access a data structure,
     * using synchronized methods.
     * @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:

    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 lll;
    
    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();
      }
    }

    实验2 编程练习

    package lll;
    
    public class Demo {
    	public static void main(String[] args) {
    		Runnable runnable = new MyThread();
    		new Thread(runnable).start();
    		new Thread(runnable).start();
    		new Thread(runnable).start();
    	}
    
    	public static class MyThread implements Runnable{ 
    		private int tickets=10; 
    		public void run() { 
    			while(tickets>0){ 
    				System.out.println(Thread.currentThread().getName() + "窗口售:第" + tickets-- + "张票"); 
    				} 
    			} 
    		}
    }

    实验总结:

       本周我们继续学习了同步线程的相关知识,了解了并发多线程的两种解决方法,一种是锁对象,还有一种是synchronized关键字。还有wait()、notify 和notifyAll()方法。

       这学期Java我们已经学到了最后一章,在这将近一个学期的学习中感谢有老师悉心的传授我知识,还有告诉了我们很多的不论是Java学习还是其他方面的道理。还有学长每次不厌其烦的为我们演示代码,给我们分享自己的经验,牺牲了很多自己的时间。

       在以后的学习力我会继续完善在这门语言学习中我的不足,也会铭记老师的教诲,不会学完之后就忘记,而是学会使用这门语言解决以后学习中的问题。

       在这里对老师和学长再次表示真挚的感谢。

  • 相关阅读:
    elasticsearch 中的Multi Match Query
    activiti 流程部署的各种方式
    elasticsearch 嵌套对象之嵌套类型
    elasticsearch Java High Level REST 相关操作封装
    elasticsearch 字段数据类型
    ubuntu 安装 docker
    elasticsearch 通过HTTP RESTful API 操作数据
    facenet 人脸识别(二)——创建人脸库搭建人脸识别系统
    POJ 3093 Margaritas(Kind of wine) on the River Walk (背包方案统计)
    墨卡托投影, GPS 坐标转像素, GPS 坐标转距离
  • 原文地址:https://www.cnblogs.com/Weiron/p/10163823.html
Copyright © 2011-2022 走看看