Java多线程与并发库高级应用详解

  1. 传统线程技术回顾
    传统是相对于JDK1.5而言的
    传统线程技术与JDK1.5的线程并发库
    线程就是程序的一条执行线索/线路。
    创建线程的两种传统方式
    1.创建Thread的子类,覆盖其中的run方法,运行这个子类的start方法即可开启线程
    Thread thread = new Thread()
    { @Override
    public void run()
    {
    while (true)
    {
    获取当前线程对象 获取线程名字
    Thread.currentThread() threadObj.getName()
    让线程暂停,休眠,此方法会抛出中断异常InterruptedException
    Thread.sleep(毫秒值);
    }
    }
    };
    thread.start();
    2.创建Thread时传递一个实现Runnable接口的对象实例
    Thread thread = new Thread(new Runnable()
    {
    public void run()
    {}
    });
    thread.start();

问题:下边的线程运行的是Thread子类中的方法还是实现Runnable接口类的方法
new Thread(
b、传递实现Runnable接口的对象
new Runnable()
{
public void run()
{}
}
){
a、覆盖Thread子类run方法
public void run(){}
}.start();
分析:new Thread(Runnable.run()){run()}.start();
子类run方法实际就是覆盖父类中的run方法,如果覆盖了就用子类的run方法,不会再找Runnable中的run方法了,所以运行的是子类中的run方法

总结:
由Thread类中的run方法源代码中看出,两种传统创建线程的方式都是在调用Thread对象的run方法,如果Thread对象的run方法没有被覆盖,并且像上边的问题那样为Thread对象传递了一个Runnable对象,就会调用Runnable对象的run方法。
多线程并不一定会提高程序的运行效率。举例:一个人同时在三张桌子做馒头
多线程下载:并不是自己电脑快了,而是抢到更多服务器资源。例:服务器为一个客户分配一个20K的线程下载,你用多个线程,服务器以为是多个用户就分配了多个20K的资源给你。

  1. 传统定时器技术回顾
    传统定时器的创建:直接使用定时器类Timer
    a、过多长时间后炸
    new Timer().schedule(TimerTask定时任务, Date time定的时间);
    b、过多长时间后炸,以后每隔多少时间再炸
    new Timer().schedule(TimerTask定时任务, Long延迟(第一次执行)时间, Long间隔时间);
    TimerTask与Runnable类似,有一个run方法
    Timer是定时器对象,到时间后会触发炸弹(TimerTask)对象
    示例:
    new Timer().schedule(
    new TimerTask()定时执行的任务
    {
    public void run()
    {
    SOP(“bombing”);
    }
    显示计时信息
    while (true)
    {
    SOP(new Date().getSeconds());
    Thread.sleep(1000);
    }
    },
    10 定好的延迟时间,10秒以后执行任务
    );
    问题:2秒后炸,爆炸后每隔3秒再炸一次
    定时器2秒后炸,炸弹里还有定时器(每3秒炸一次)
    class MyTimerTask extends TimerTask 这就是准备用的子母弹
    {
    public void run()
    {
    本身就是一颗炸弹
    SOP(bombing);
    内部子弹
    new Timer().schedule(
    new MyTimerTask(), 2000
    );
    }
    }
    放置子母弹,2秒后引爆
    new Timer().schedule(new MyTimerTask(), 2000);
    问题延伸:
    上面的问题延伸,母弹炸过后,子弹每隔3秒炸一次,再每隔8秒炸一次
    1、在MyTimerTask内部定义一个静态变量记录炸弹号,在run方法内将炸弹号加1,每次产生新炸弹,号码就会加1,根据炸弹号判断是3秒炸还是8秒炸。
    注意:内部类中不能声明静态变量
    定义一个静态变量private static count = 0;
    在run方法内部:count=(count+1)%2;
    将定时器的时间设置为:2000+2000*count
    2、用两个炸弹来完成,A炸弹炸完后启动定时器安装B炸弹,B炸弹炸完后也启动一个定时器安装A炸弹。

定时器还可以设置具体时间,如某年某月某日某时……可以设置周一到周五做某事,自己设置的话需要换算日期时间,可以使用开源工具quartz来完成。

  1. 传统线程互斥技术
    线程安全问题例子:银行转账
    同一个账户一边进行出账操作(自己交学费),另一边进行入账操作(别人给自己付款),线程不同步带来的安全问题
    示例:逐个字符的方式打印字符串
    class Outputer
    {
    public void output(String name)
    {
    int len = name.length();
    for (int i=0; i

猜你喜欢

转载自blog.csdn.net/HelloMy_World/article/details/81504574