• 0803作业


    多线程作业

     

    一、 填空题

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

     

    二、 选择题

    1.

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

    A

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

    B.

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

    C.

    Thread类属于java.util程序包*

    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!");

    }

    }

    D.选项输出   main

    A.

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

    B.

    Test t = new Test();

    C.

    Thread t = new Test();

    D.

    Thread t = new Thread();   main

     

    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 {jicjic继承

    void run( ) {

    }

    }

    C.

    public class MyRunnable  implements Runnable  {实现

    public void run( ) {

    }

    }

    D.

    public class MyRunnable  implements Runnable  {实现,没public

    void run( ) {

    }

    }

     

    4.

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

    A

    阻塞状态

    B.

    运行状态

    C.

    就绪状态

    D.

    新建状态

     

    5.

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

    A

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

    B.

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

    C.

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

    D.

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

     

    6.

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

    A

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

    B.

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

    C.

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

    D.

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

     

    7.

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

    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.

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

    A.

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

    B.

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

    C.

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

    D.

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

     

     

    三、 简答题

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

    定义类继承Thread

    定义类实现Runnable接口

    继承Thread : 由于子类重写了Thread类的run(), 当调用start()时, 直接找子类的run()方法(~是由java虚拟机调用的)
    实现Runnable : 构造函数中传入了Runnable的引用, 成员变量(this.target)记住了它, start()调用run()方法时内部判断成员变量(Runnable的引用:target)是否为空, 不为空编译时看的是Runnable的run(),运行时执行的是子类的run()方法

    继承Thread
    好处是:可以直接使用Thread类中的方法,代码简单
    弊端是:如果已经有了父类,就不能用这种方法
    实现Runnable接口
    好处是:即使自己定义的线程类有了父类也没关系,因为有了父类也可以实现接口,而且接口是可以多实现的
    弊端是:不能直接使用Thread中的方法需要先获取到线程对象后,才能得到Thread的方法,代码复杂

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

    sleep()睡眠时,保持对象锁,仍然占有该锁;

    wait()睡眠时,释放对象锁。

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

    调用某个对象的wait()方法能让当前线程阻塞,并且当前线程必须拥有此对象的monitor(即锁)

    调用某个对象的notify()方法能够唤醒一个正在等待这个对象的monitor的线程,如果有多个线程都在等待这个对象的monitor,则只能唤醒其中一个线程;

    调用notifyAll()方法能够唤醒所有正在等待这个对象的monitor的线程;

     

    四、 编码

    1.设计一个多线程的程序如下:设计一个火车售票模拟程序。假如火车站要有100张火车票要卖出,现在有5个售票点同时售票,用5个线程模拟这5个售票点的售票情况。

     

    package com.wty.thread;
    
    public class Demo1_Runnable {
    
    	public static void main(String[] args) {
    		Tickets t = new Tickets();
    		Thread t1 = new Thread(t);         
    		t1.start();
    		Thread t2 = new Thread(t);         
    		t2.start();
    		Thread t3 = new Thread(t);         
    		t3.start();
    		Thread t4 = new Thread(t);         
    		t4.start();
    		Thread t5 = new Thread(t);         
    		t5.start();
    		
    		t1.setName("一号窗口");
    		t2.setName("二号窗口");
    		t3.setName("三号窗口");
    		t4.setName("四号窗口");
    		t5.setName("五号窗口");
    	}
    
    }
    
    class Tickets implements Runnable{
    	private  int tickets = 100;
    	public void run() {
    		while (true) {
    			synchronized (Tickets.class) {
    				if (tickets <= 0) {
    					break;
    				}
    				try {
    					Thread.sleep(10);
    				} catch (InterruptedException e) {
    					
    					e.printStackTrace();
    				}
    				System.out.println(Thread.currentThread().getName()+"正在出售车票,第"+(100 - (--tickets)) + "张票,余票" + tickets + "张!");
    			}
    		}
    		
    	}
    }
    

     

      

     

    2.编写两个线程,一个线程打印1-52的整数,另一个线程打印字母A-Z。打印顺序为12A34B56C….5152Z。即按照整数和字母的顺序从小到大打印,并且每打印两个整数后,打印一个字母,交替循环打印,直到打印到整数52和字母Z结束。

    要求:

    1) 编写打印类Printer,声明私有属性index,初始值为1,用来表示是第几次打印。

    2) 在打印类Printer中编写打印数字的方法print(int i)3的倍数就使用wait()方法等待,否则就输出i,使用notifyAll()进行唤醒其它线程。

    3) 在打印类Printer中编写打印字母的方法print(char c),不是3的倍数就等待,否则就打印输出字母c,使用notifyAll()进行唤醒其它线程。

    4) 编写打印数字的线程NumberPrinter继承Thread类,声明私有属性private Printer p;在构造方法中进行赋值,实现父类的run方法,调用Printer类中的输出数字的方法。

    5) 编写打印字母的线程LetterPrinter继承Thread类,声明私有属性private Printer p;在构造方法中进行赋值,实现父类的run方法,调用Printer类中的输出字母的方法。

    6) 编写测试类Test,创建打印类对象,创建两个线程类对象,启动线程。

    package test;
    
    public class Test {
    	public static void main(String[] args) {
    		Printer p = new Printer();
    		Thread t1 = new NumberPrinter(p);
    		Thread t2 = new LetterPrinter(p);
    		t1.start();
    		t2.start();
    		
    	}
    }
    
    
    class Printer {
    	private int index = 1;//声明私有属性index,初始值为1,用来表示是第几次打印。
    	
    	public synchronized void print(int i)  {
    		while (index % 3 == 0) {
    			try {
    				wait();
    			} catch (Exception e) {
    				
    				e.printStackTrace();
    			}
    		}
    		System.out.print(" " + i);
    		index++;
    		notifyAll();
    	}
    	
    	public synchronized void print(char c) {
    		while (index % 3 != 0) {
    			try {
    				wait();
    			} catch (Exception e) {
    				
    				e.printStackTrace();
    			}
    		}
    		System.out.print(" " + c);
    		System.out.println("
    ");
    		index++;
    		notifyAll();
    	}
    }
    
    class NumberPrinter extends Thread {
    	private Printer p;
    	public NumberPrinter(Printer p){
    		this.p = p;
    	}
    	public void run() {
    		for (int i = 1; i <=52; i++) {
    			p.print(i);
    		}
    	}
    }
    
    class LetterPrinter extends Thread {
    	private Printer p;
    	public LetterPrinter(Printer p){
    		this.p = p;
    	}
    	public void run() {
    		for (char c = 'A'; c <= 'Z'; c++) {
    			p.print(c);
    		}
    	}
    	
    }
    

      

    五、 可选题

    1. 设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1

    要求:使用内部类实现线程,对j增减的时候不考虑顺序问题。

    package test;
    
    public class Test3 {
    
        private int j;
    
        public static void main(String[] args) {
            
        	Test3 t3 = new Test3();
            Add add = t3.new Add();
            Minus minus = t3.new Minus();
            for (int i = 0; i < 2; i++) {
                Thread t = new Thread();
               
                t = new Thread(add);
                t.start();
                t = new Thread(minus);
                t.start();
            }
        }
    
        private synchronized void Add() {
            j++;
            System.out.println(Thread.currentThread().getName() + "对j" + j + " Add");
        }
    
        private synchronized void Minus() {
            j--;
            System.out.println(Thread.currentThread().getName() + "对j" + j + " Minus");
        }
    
        class Add implements Runnable {
    
            @Override
            public void run() {
                
                for (int i = 0; i < 10; i++) {
                    Add();
                	
                }
            }
    
        }
    
        class Minus implements Runnable {
    
            @Override
            public void run() {
                
                for (int i = 0; i < 10; i++) {
                	Minus();
                }
            }
    
        }
    }
    

      

     

    2.编写多线程程序,模拟多个人通过一个山洞的模拟。这个山洞每次只能通过一个人,每个人通过山洞的时间为5秒,有10个人同时准备过此山洞,显示每次通过山洞人的姓名和顺序。

    package test;
    
    public abstract class GuoShanDong implements Runnable {
    	
    	public static void main(String[] args){
    
    		Tunnel tul = new Tunnel();
    	
    		Thread p1 = new Thread(tul, "赵");
    		Thread p2 = new Thread(tul, "钱");
    		Thread p3 = new Thread(tul, "孙");
    		Thread p4 = new Thread(tul, "李");
    		Thread p5 = new Thread(tul, "周");
    		Thread p6 = new Thread(tul, "吴");
    		Thread p7 = new Thread(tul, "郑");
    		Thread p8 = new Thread(tul, "王");
    		Thread p9 = new Thread(tul, "冯");
    		Thread p0 = new Thread(tul, "陈");
    
    		p1.start();
    		p2.start();
    		p3.start();
    		p4.start();
    		p5.start();
    		p6.start();
    		p7.start();
    		p8.start();
    		p9.start();
    		p0.start();
    	}
    }
    
    class Tunnel implements Runnable {
    
        int crossedNum = 0;
    
        public void run() {
            cross();
        }
        public synchronized void cross() {
            try
            {
                Thread.sleep(5000);
            } catch (InterruptedException e)
            
            {
                e.printStackTrace();
            }
            crossedNum++;
    			System.out.println(Thread.currentThread().getName()+ "通过了"
                		+ "山洞,这是第" + crossedNum + "个通过的"); 
        }
    }
    

      

  • 相关阅读:
    项目结束后一点心得
    提交disabled按钮的几种方法
    发现VS2005一个BUG
    单一文件上传防止粘帖及格式限制
    MessageBox.Show常用的2个方法
    一点感受一点体会
    EXCEL导入GridView,然后再汇入数据库.
    2根ECC内存
    (转载)gridview添加删除确认对话框
    反射调用Method
  • 原文地址:https://www.cnblogs.com/wty1994/p/9418836.html
Copyright © 2020-2023  润新知