java第九章

1.FutureTask类有什么作用?它实现了哪些接口?Callable接口和Runnable接口有什么不同?
Callable需要实现call方法,而Runnable需要实现run方法;并且,call方法还可以返回任何对象,无论是什么对象,JVM都会当作Object来处理。但是如果使用了泛型,我们就不用每次都对Object进行转换了。

区别:
Callable可以返回一个类型V,而Runnable不可以
Callable能够抛出checked exception,而Runnable不可以。
Runnable是自从java1.1就存在,而Callable是1.5之后才加上去的。
Callable和Runnable都可以应用于executors。而Thread类只支持Runnable。

2.请查阅JDK自学线程池的相关类,如ThreadPoolExecutor构造器各个参数的意义, 利用线程池编写多线程程序。

public class ThreadPoolDemo1 implements Runnable{

    public static void main(String[] args) {
        //创建有界队列
        ArrayBlockingQueue<Runnable> queue=new ArrayBlockingQueue<Runnable>(12);
//        LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>(12);
        //Executors工厂类底层用的就是ThreadPoolExecutor
        //核心4 最大池8
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(4, 8, 60, TimeUnit.SECONDS, queue);
        for (int i = 0; i < 30; i++)
        {
            //放入任务,当核心线程数满了之后,就会把任务加到队列中去
            threadPool.execute(
                    new Thread(new ThreadPoolDemo1(), "Thread".concat(i + "")));
//            System.out.println("线程池中活跃的线程数: " +threadPool.getPoolSize()+",核心线程数:"+ threadPool.getCorePoolSize()+",最大线程数:"+threadPool.getMaximumPoolSize());
            if (queue.size() > 0)
            {
                System.out.println("阻塞队列有线程了,队列中阻塞的线程数:" + queue.size()+", 线程池中执行任务的线程数:"+threadPool.getActiveCount());
            }
            System.out.println(" 线程池中当前的线程数:" +threadPool.getPoolSize());

        }
        threadPool.shutdown();
    }

    @Override
    public void run() {
        try
        {
            Thread.sleep(100);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }
}

3.volatile关键字有什么作用?
1、保证该变量对所有线程的可见性;
2、禁止指令重排序优化。

4.Java提供了哪些同步机制来实现互斥
Java 提供了两种锁机制来控制多个线程对共享资源的互斥访问,第一个是 JVM 实现的 synchronized,而另一个是 JDK 实现的 ReentrantLock。
两者比较
1.锁的实现
synchronized 是 JVM 实现的,而 ReentrantLock 是 JDK 实现的。

2.性能
新版本 Java 对 synchronized 进行了很多优化,例如自旋锁等,synchronized 与 ReentrantLock 大致相同。

3.等待可中断
当持有锁的线程长期不释放锁的时候,正在等待的线程可以选择放弃等待,改为处理其他事情。

ReentrantLock 可中断,而 synchronized 不行。

4.公平锁
公平锁是指多个线程在等待同一个锁时,必须按照申请锁的时间顺序来依次获得锁。

synchronized 中的锁是非公平的,ReentrantLock 默认情况下也是非公平的,但是也可以是公平的。

5.锁绑定多个条件
一个 ReentrantLock 可以同时绑定多个 Condition 对象。

5.编写Java程序模拟烧水泡茶最优工序。

package homework.third;

public class MakeTea {
	public static void main(String[] args) {
		MakeTeaThread1 mk1=new MakeTeaThread1();
		mk1.start();
	}
}
package homework.third;

public class MakeTeaThread1 extends Thread{
	private MakeTeaThread2 mk2;
	
	public MakeTeaThread1() {
		mk2=new MakeTeaThread2();
	}
	
	public void run() {
		System.out.print(this.getName()+":洗水壶->");
		try {
			Thread.sleep(1000);
		}
		catch(Exception e) {}
		System.out.println("烧水-------------------");
		System.out.print("                                     |");
		mk2.start();
		try {
			Thread.sleep(15000);
		}
		catch(Exception e) {}
		System.out.println();
		System.out.print(Thread.currentThread().getName()+":                          泡茶");
	}
}

package homework.third;

public class MakeTeaThread2 extends Thread{
	public void run() {
		System.out.println();
		System.out.print(this.getName()+":     洗茶壶->");
		try {
			Thread.sleep(1000);
		}
		catch(Exception e) {}
		System.out.print("洗茶杯->");
		try {
			Thread.sleep(2000);
		}
		catch(Exception e) {}
		System.out.println("拿茶叶------");
		System.out.print("                                     ↓");
	}
}

6.请使用Java并发包的Lock及Conditon改写例9.11。

import java.util.concurrent.locks.*;
class Account{
    volatile private int value;
    //布尔标志              
    volatile private boolean isMoney = false;   
    private final ReentrantLock lock = new ReentrantLock();
    // 存钱的 Condition 对象
    private Condition SaveCondition = lock.newCondition();
    // 取钱的 Condition 对象
    private Condition FetchCondition = lock.newCondition();
}
//存钱
void put(int i) {
     lock.lock(); //使用锁取代同步方法
     try{ 
         while(isMoney){
             try{ 
                 SaveCondition.await(); //存钱线程等待
             } catch(Exception e){}
         }
         value = value + i; 
         System.out.println("存入"+i+" 账上金额为:"+value);
         isMoney = true;//设置标志
         FetchCondition.signal(); //唤醒等待资源的取钱线程
         } finally {
             lock.unlock();
         }
}
//取钱
int get(int i) { 
    lock.lock(); 
    try{
        while(!isMoney ){
           try { 
               FetchCondition.await(); //取钱线程等待
           } catch(Exception e){}
        }
        if (value>i)
            value = value - i;         
         else {  
            i = value;
            value = 0; }
         System.out.println("取走"+i+" 账上金额为:"+value);
         isMoney = false;
         SaveCondition.signal(); //唤醒等待资源的存钱线程
         return i;                      
        } finally {
               lock.unlock();}
   }

7.编写一个多线程Java应用模拟生产者/消费者模型,各产生10个生产者和消费者线程,共享一个缓冲区队列(长度自设),生产者线程将产品放入到缓冲区,消费者线程从缓冲区取出产品。

class ThreadA implements Runnable{
    int t = 0;
    Thread tb = new Thread(new Runnable() {
        int t = 1;
      
        public void run() {
            while (t<6) {

                if(t == 1) System.out.println("第"+t+"min:开始洗茶壶");
                else if (t == 2) {
                    System.out.println("第"+t+"min:洗茶壶完成\n" +"第"+t+"min:开始洗茶杯");
                }
                else if (t == 4) {
                    System.out.println("第"+t+"min:洗茶杯完成\n"+"第"+t+"min:开始拿茶叶");
                }
                else if (t == 5) {
                    System.out.println("第"+t+"min:拿茶叶完成");
                }
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                t++;
            }
        }
    });


    public void run() {
        while (t <= 16 ) {
            if (t == 0) System.out.println("第"+t+"min:开始洗水壶");
            else if (t == 1) {
                System.out.println("第"+t+"min:洗水壶完成\n"+"第"+t+"min:开始烧水");
                tb.start();
            }
            else if (t == 16) {
                System.out.println("第"+t+"min:泡茶");
            }
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            t++;
        }
    }
}

public class Tea {
    public static void main(String[] args) {
        ThreadA tta = new ThreadA();
        Thread ta = new Thread(tta);
        ta.start();
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值