zoukankan      html  css  js  c++  java
  • 多线程作业

    多线程作业

     

    一、    填空题

    1. 处于运行状态的线程在某些情况下,如执行了sleep(睡眠)方法,或等待I/O设备等资源,将让出CPU并暂时停止自己的运行,进入___阻塞______状态。
    2. 处于新建状态的线程被启动后,将进入线程队列排队等待CPU,此时它已具备了运行条件,一旦轮到享用CPU资源就可以获得执行机会。上述线程是处于     就绪         状态。
    3. 一个正在执行的线程可能被人为地中断,让出CPU的使用权,暂时中止自己的执行,进入   阻塞         状态。
    4. 在Java中编写实现多线程应用有两种途径:一种是继承Thread类创建线程,另一种是实现    Runnable         接口创建线程。
    5. 在线程控制中,可以调用_____join()_______方法,阻塞当前正在执行的线程,等插队线程执行完后后再执行阻塞线程。
    6. 多线程访问某个共享资源可能出现线程安全问题,此时可以使用____synchronized____________关键字来实现线程同步,从而避免安全问题出现,但会影响性能,甚至出现死锁。
    7.  在线程通信中,调用wait( )可以是当前线程处于等待状态,而为了唤醒一个等待的线程,需要调用的方法是___notify()___________。
    8. 在线程通信中,可以调用wait()、notify()、notifyAll()三个方法实现线程通信,这三个方法都是______Object________类提供的public方法,所以任何类都具有这三个方法。

     

    二、    选择题

    1.

    下列关于Java线程的说法正确的是( A   )。(选择一项)

     

     

     

     

    A

    每一个Java线程可以看成由代码、一个真实的CPU以及数据三部分组成

     

    B.

    创建线程的两种方法中,从Thread类中继承方式可以防止出现多父类的问题

     

    C.

    Thread类属于java.util程序包(java.lang.Thread)

     

    D.

    使用new Thread(new X()).run();方法启动一个线程

     

    2.

    以下选项中可以填写到横线处,让代码正确编译和运行的是( A   。(选择一项)

     

    public class Test implements Runnable {

             public static void main(String[] args) {

                      ___________________________________

                      t.start();

                      System.out.println("main");

             }

             public void run() {

                      System.out.println("thread1!");

             }

    }

     

     

     

     

    A.

    Thread t = new Thread(new Test());

     

    B.

    Test t = new Test();

     

    C.

    Thread t = new Test();          

     

    D.

    Thread t = new Thread();

     

    3.

    如下代码创建一个新线程并启动线程,问:四个选项中可以保证正确代码创建target对象,并能编译正确的是(  C   )?(选择一项)

     

    public static void main(String[] args) {

              Runnable target=new MyRunnable( ); 

              Thread myThread=new Thread(target);

    }

     

     

     

     

    A

    public class MyRunnable extends Runnable {

             public void run( ) {

     

             }

    }

     

    B.

    public class MyRunnable extends Runnable {

             void run( ) {

     

             }

    }

     

    C.

    public class MyRunnable  implements Runnable  {

             public void run( ) {

     

             }

    }

     

    D.

    public class MyRunnable  implements Runnable  {

             void run( ) {

    }

    }

     

    4.

    当线程调用start( )后,其所处状态为( C   )。(选择一项)

     

     

     

     

    A

    阻塞状态

     

    B.

    运行状态

     

    C.

    就绪状态

     

    D.

    新建状态

     

    5.

    下列关于Thread类提供的线程控制方法的说法中,错误的是(C    )。(选择一项)

     

     

     

     

    A

    线程A中执行线程B的join()方法,则线程A等待直到B执行完成

     

    B.

    线程A通过调用interrupt()方法来中断其阻塞状态

     

    C.

    若线程A调用方法isAlive()返回值为false,则说明A正在执行中,也可能是可运行状态

     

    D.

    currentThread()方法返回当前线程的引用

     

    6.

    下列关于线程的优先级说法中,正确的是(  B C  )。(选择两项)

     

     

     

     

    A

    线程的优先级是不能改变的

     

    B.

    线程的优先级是在创建线程时设置的

     

    C.

    在创建线程后的任何时候都可以重新设置

     

    D.

    线程的优先级的范围在1-100之间

     

    7.

    以下选项中关于Java中线程控制方法的说法正确的是( A D   )。(选择二项)

     

     

     

     

    A.

    join ( ) 的作用是阻塞指定线程等到另一个线程完成以后再继续执行

     

    B.

    sleep ( ) 的作用是让当前正在执行线程暂停,线程将转入就绪状态  阻塞

     

    C.

    yield ( ) 的作用是使线程停止运行一段时间,将处于阻塞状态   就绪

     

    D.

    setDaemon( )的作用是将指定的线程设置成后台线程

     

    8.

    在多个线程访问同一个资源时,可以使用(  A  关键字来实现线程同步,保证对资源安全访问。(选择一项)

     

     

     

     

    A.

    synchronized

     

    B.

    transient

     

    C.

    static

     

    D.

    yield

     

    9.

    Java中线程安全问题是通过关键字(  C   )解决的?。(选择一项)

     

     

     

     

    A.

    finally

     

    B.

    wait( )

     

    C.

    synchronized

     

    D.

    notify( )

    10.

    以下说法中关于线程通信的说法错误的是(    D?。(选择一项)

     

     

     

     

    A.

    可以调用wait()、notify()、notifyAll()三个方法实现线程通信

     

    B.

    wait()、notify()、notifyAll()必须在synchronized方法或者代码块中使用

     

    C.

    wait()有多个重载的方法,可以指定等待的时间

     

    D.

    wait()、notify()、notifyAll()是Object类提供的方法,子类可以重写

     

    三、    判断题

    1. 进程是线程Thread内部的一个执行单元,它是程序中一个单一顺序控制流程。( F  )
    2. 一个进程可以包括多个线程。两者的一个主要区别是:线程是资源分配的单位,而进程CPU调度和执行的单位。( F   )
    3. 用new关键字建立一个线程对象后,该线程对象就处于新生状态。处于新生状态的线程有自己的内存空间,通过调用start进入就绪状态。( T   )
    4. 线程可以用yield使低优先级的线程运行。( T   )
    5. Thread.sleep( )方法调用后,当等待时间未到,该线程所处状态为阻塞状态。当等待时间已到,该线程所处状态为运行状态。( F   )  就绪
    6. 当一个线程进入一个对象的一个synchronized方法后,其它线程不可以再进入该对象同步的其它方法执行。( T  )

     

    四、    简答题

    1. 简述进程和线程的联系和区别。

        进程:一个程序对一个数据集的动态执行过程,是分配资源的基本单位,是资源分配的最小单位
        线程:一个进程内的基本调度单位, CPU调度和执行的单位,是程序执行的最小单位

        区别:进程是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位

    1. 创建线程的两种方式分别是什么?各有什么优缺点

        第一种方式:使用Runnable接口创建线程,重写run方法
        第二种方式:直接继承Thread类创建对象,重写run方法

        Runnable:接口方案的优点:降低类与类的耦合性,缺点是书写复杂

        Thread继承方案的优点:书写简单,缺点是耦合性太高 

    1. 请你简述sleep( )和wait( )有什么区别?

      (1)同步锁的对待不同:

        sleep()后,程序并不会不释放同步锁。

        wait()后,程序会释放同步锁。

      (2)用法的不同:

        sleep()可以用时间指定来使他自动醒过来。如果时间不到你只能调用interreput()来强行打断。

        wait()可以用notify()直接唤起。

    1. Java中实现线程通信的三个方法及其作用。

        在Java中,可以通过配合调用Object对象的wait()方法和notify()方法或notifyAll()方法来实现线程间的通信。

        作用:当线程执行wait()方法时候,会释放当前的锁,然后让出CPU,进入等待状态。只有当 notify/notifyAll() 被执行时候,才会唤醒一个或多个正处于等待状态的线程,然后继续往下执行,直到执行完synchronized 代码块的代码或是中途遇到wait() ,再次释放锁。

      1 一、    编码题
      2 1.    设计一个多线程的程序如下:设计一个火车售票模拟程序。假如火车站要有100张火车票要卖出,现在有5个售票点同时售票,用5个线程模拟这5个售票点的售票情况。
      3 
      4 public class test_1 {
      5     public static void main(String[] args) {
      6         //创建1个资源共享类
      7         TrainTickets tr = new TrainTickets();
      8         //创建5个售票点多线程,并且给多线程起名
      9         Thread t1 = new Thread(tr, "售票点1");
     10         Thread t2 = new Thread(tr, "售票点2");
     11         Thread t3 = new Thread(tr, "售票点3");
     12         Thread t4 = new Thread(tr, "售票点4");
     13         Thread t5 = new Thread(tr, "售票点5");
     14         //启动多线程
     15         t1.start();
     16         t2.start();
     17         t3.start();
     18         t4.start();
     19         t5.start();
     20     }
     21 }
     22 public class TrainTickets implements Runnable {
     23     int tickets = 100;
     24     @Override
     25     public void run() {
     26         while(true){
     27             sellTickets();
     28         }
     29     }
     30     public synchronized void sellTickets(){
     31         if(tickets>0){
     32             try {
     33                 Thread.sleep(10);
     34                 System.out.println(Thread.currentThread().getName()+":正在出售"+(tickets--)+"张票!");
     35             } catch (InterruptedException e) {
     36                 e.printStackTrace();
     37             }
     38         }
     39     }
     40 }
     41 
     42 
     43 2.    编写两个线程,一个线程打印1-52的整数,另一个线程打印字母A-Z。打印顺序为12A34B56C….5152Z。即按照整数和字母的顺序从小到大打印,并且每打印两个整数后,打印一个字母,交替循环打印,直到打印到整数52和字母Z结束。
     44 要求:
     45 1)    编写打印类Printer,声明私有属性index,初始值为1,用来表示是第几次打印。
     46 2)    在打印类Printer中编写打印数字的方法print(int i),3的倍数就使用wait()方法等待,否则就输出i,使用notifyAll()进行唤醒其它线程。
     47 3)    在打印类Printer中编写打印字母的方法print(char c),不是3的倍数就等待,否则就打印输出字母c,使用notifyAll()进行唤醒其它线程。
     48 4)    编写打印数字的线程NumberPrinter继承Thread类,声明私有属性private Printer p;在构造方法中进行赋值,实现父类的run方法,调用Printer类中的输出数字的方法。
     49 5)    编写打印字母的线程LetterPrinter继承Thread类,声明私有属性private Printer p;在构造方法中进行赋值,实现父类的run方法,调用Printer类中的输出字母的方法。
     50 6)    编写测试类Test,创建打印类对象,创建两个线程类对象,启动线程。
     51 
     52 public class Printer {
     53 /**
     54        *1)编写打印类Printer,声明私有属性index,初始值为1,用来表示是第几次打印。
     55        * 2)    在打印类Printer中编写打印数字的方法print(int i),3的倍数就使用wait()方法等待,
     56        * 否则就输出i,使用notifyAll()进行唤醒其它线程。
     57        * 3)    在打印类Printer中编写打印字母的方法print(char c),不是3的倍数就等待,
     58        * 否则就打印输出字母c,使用notifyAll()进行唤醒其它线程。
     59  */
     60     private int index = 1;
     61     //打印数字的方法print(int i)
     62     public synchronized void print(int i){
     63         if(index%3==0){
     64             try {
     65                 wait();
     66             } catch (InterruptedException e) {
     67                 e.printStackTrace();
     68             }
     69         }
     70             System.out.print(i);
     71             index++;
     72             notifyAll();
     73     }
     74     public synchronized void print(char c){
     75         if(index%3!=0){
     76             try {
     77                 wait();
     78             } catch (InterruptedException e) {
     79                 e.printStackTrace();
     80             }
     81         }
     82             System.out.print(c);
     83             index++;
     84             notifyAll();
     85     }
     86 }
     87 public class NumberPrinter extends Thread{
     88 /**
     89  *  4)编写打印数字的线程NumberPrinter继承Thread类,声明私有属性private Printer p;
     90    * 在构造方法中进行赋值,实现父类的run方法,调用Printer类中的输出数字的方法。
     91  */
     92     private Printer p;
     93 
     94     public NumberPrinter(Printer p) {
     95         this.p = p;
     96     }
     97     @Override
     98         public void run() {
     99             for(int i=1;i<53;i++){
    100                 p.print(i);
    101             }
    102         }
    103 }
    104 public class LetterPrinter extends Thread{
    105 /**
    106  *  * 5)编写打印字母的线程LetterPrinter继承Thread类,声明私有属性private Printer p;
    107        * 在构造方法中进行赋值,实现父类的run方法,调用Printer类中的输出字母的方法。
    108  */
    109     private Printer p;
    110 
    111     public LetterPrinter(Printer p) {
    112         this.p = p;
    113     }
    114     @Override
    115         public void run() {
    116            for(char j='A';j<='Z';j++){
    117                p.print(j);
    118            }
    119         }
    120 }
    121 public class test_2 {
    122   /**
    123  * 6)    编写测试类Test,创建打印类对象,创建两个线程类对象,启动线程。
    124    */
    125     public static void main(String[] args) {
    126         //创建公共打印资源对象
    127         Printer p = new Printer();
    128         //创建数字打印线程
    129         Thread t1 = new NumberPrinter(p);
    130         //创建字母打印线程
    131         Thread t2 = new LetterPrinter(p);
    132         //启动线程
    133         t1.start();
    134         t2.start();
    135     }
    136 }
    137 
    138 二、    可选题
    139 1.    设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。
    140 要求:使用内部类实现线程,对j增减的时候不考虑顺序问题。
    141 public class test_3 {
    142     public static void main(String[] args) {
    143         //创建公共资源类
    144         public_3 p =new public_3();
    145         //创建自加线程,并命名
    146         Thread t1 = new appded(p);
    147         t1.setName("自增");
    148         //创建自减线程,并命名
    149         Thread t2 = new subtract(p);
    150         t2.setName("自减");
    151         //启动线程
    152         t1.start();
    153         t2.start();
    154     }
    155 }
    156 public class public_3 {
    157     //+1
    158     private int j = 1;
    159     public synchronized void appded(){
    160         j++;
    161         System.out.println(Thread.currentThread().getName()+":j++="+j);
    162     }
    163     public synchronized void subtract(){
    164         j--;
    165         System.out.println(Thread.currentThread().getName()+":j--="+j);
    166     }
    167 }
    168 public class appded extends Thread{
    169    public_3 p = new public_3();
    170    
    171     public appded(public_3 p) {
    172     this.p = p;
    173 }
    174     @Override
    175     public void run() {
    176         for (int i = 1; i < 10; i++) {
    177             p.appded();
    178         }
    179     }
    180 }
    181 public class subtract extends Thread {
    182     public_3 p =new public_3();
    183     public subtract(public_3 p) {
    184         this.p = p;
    185     }
    186     @Override
    187     public void run() {
    188         for (int i = 1; i < 10; i++) {
    189             p.subtract();
    190         }
    191     }
    192 }
    193 2.    编写多线程程序,模拟多个人通过一个山洞的模拟。这个山洞每次只能通过一个人,每个人通过山洞的时间为5秒,有10个人同时准备过此山洞,显示每次通过山洞人的姓名和顺序。
    194 
    195 public class test_4 {
    196     public static void main(String[] args) {
    197         //创建山洞线程
    198         Hole h = new Hole();
    199         //创建10个人的线程
    200         Thread t1 = new Thread(h,"秦始皇");
    201         Thread t2 = new Thread(h,"刘邦");
    202         Thread t3 = new Thread(h,"刘策");
    203         Thread t4 = new Thread(h,"杨坚");
    204         Thread t5 = new Thread(h,"李世民");
    205         Thread t6 = new Thread(h,"赵匡胤");
    206         Thread t7 = new Thread(h,"成吉思汗");
    207         Thread t8 = new Thread(h,"朱元璋");
    208         Thread t9 = new Thread(h,"康熙");
    209         Thread t10 = new Thread(h,"蒋介石");
    210         t1.start();
    211         t2.start();
    212         t3.start();
    213         t4.start();
    214         t5.start();
    215         t6.start();
    216         t7.start();
    217         t8.start();
    218         t9.start();
    219         t10.start();
    220         
    221     }
    222     
    223 }
    224 public class Hole extends Thread{
    225     private static int i=1;
    226     @Override
    227     public void run() {
    228         //上锁
    229         synchronized(this){
    230             
    231             System.out.println("第"+i+"个人"+Thread.currentThread().getName()+"正在通过山洞");
    232             try {
    233                 sleep(100);
    234                 i++;
    235             } catch (InterruptedException e) {
    236                 // TODO Auto-generated catch block
    237                 e.printStackTrace();
    238             }
    239         
    240         }
    241     }
    242 
    243 }
  • 相关阅读:
    MVC入门学习笔记(五)
    IIS搭配Serveru构建企业空间服务(一)
    HTMLTextBox基于WebBrowser的HTML编辑控件
    MVC入门学习笔记(一)
    MVC入门学习笔记(七)
    MVC入门学习笔记(十)
    关注以下.NET技术
    Notification状态栏通知
    Activity设置横屏显示
    通过xml文件与代码去除通知栏和标题全屏显示
  • 原文地址:https://www.cnblogs.com/topshark/p/10251985.html
Copyright © 2011-2022 走看看