J2se_lesson3 线程

                      

 

1.多进程:在操作系统中能(同时)运行多个任务(程序)

多线程:在同一应用程序中有多个顺序流(同时)执行

 

创建线程:通过java.lang.Thread来创建一个线程

启动线程:

v  每个线程都是通过某个特定Thread对象所对应的方法run( )来完成其操作的,方法run( )称为线程体。

v  使用start()方法,线程进入Runnable(可运行)状态,它将向线程调度器注册这个线程。

v  调用start()方法并不一定马上会执行这个线程,正如上面所说,它只是进入Runnable而不是Running

v 注意,不要直接在程序中调用线程的run()方法。

 

2.Java中创建线程的两种方式:继承thread类;实现Runnable接口

**********两种创建方式,一种启动方式start*******

两种线程创建方式的比较

使用Runnable接口                  RunnableDemo,RunnableTest

可以将CPU,代码和数据分开,形成清晰的模型;还可以从其他类继承;保持程序风格的一致性。

直接继承Thread                  ThreadDemo,Test

不能再从其他类继承;编写简单,可以直接操纵线程,无需使用Thread.currentThread()

3.结束线程

v  线程会以以下三种方式之一结束:

§  线程到达其 run() 方法的末尾;

§  线程抛出一个未捕获到的 Exception Error

4.后台线程

有一种线程,它是在后台运行的,它的任务是为其他的线程提供服务,这种线程被称为"后台线程(Daemon Thread",又称为"守护线程"

 

资源有限,排队,join

 

   
    

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

5.多线程编程

§  多个线程来自同一个Runnable实例

§  多个线程使用同样的数据和代码

Java语言中,引入了对象互斥锁(mutual exclusive lock,也简称为对象锁)的概念,来保证共享数据操作的完整性:

§  每个对象都对应于一个可称为互斥锁的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。

§  关键字synchronized 来与对象的互斥锁联系。当某个对象用synchronized修饰时,表明该对象在任一时刻只能由一个线程访问。

关键字synchronized

v  Java中的两种使用synchronized的方式:

§  放在方法前面,这样,调用该方法的线程均将获得对象的锁。

§  放在代码块前面,它也有两种形式:

    synchronized (this){… …}synchronized {… …}:代码块中的代码将获得当前对象引用的锁

    synchronized(otherObj){… …}:代码块中的代码将获得指定对象引用的锁

释放锁

v  当线程执行到synchronized()块结束时,释放对象锁。

v  当在synchronized()块中遇到break, return或抛出exception,则自动释放对象锁。

v  当一个线程调用wait()方法时,它放弃拥有的对象锁并进入等待队列。

 

多线程编程一般规则

v  如果两个或两个以上的线程都修改一个对象,那么把执行修改的方法定义为被同步的,如果对象更新影响到只读方法,那么只读方法也要定义成同步的。

v  不要滥用同步。如果在一个对象内的不同的方法访问的不是同一个数据,就不要将方法设置为synchronized的。

v  如果一个线程必须等待一个对象状态发生变化,那么他应该在对象内部等待,而不是在外部。他可以通过调用一个被同步的方法,并让这个方法调用wait()

v  每当一个方法返回某个对象的锁时,它应当调用notifyAll()来让等待队列中的其他线程有机会执行。

v  记住wait()notify()/notifyAll()Object类方法,而不是Thread类的方法。仔细查看每次调用wait()方法,都有相应的notify()/notifyAll()方法,且它们均作用于同一个对象。

 

 

 

 

 

 

 

 

 

 

生产者消费者例子

/**

 * 仓库

 * @author Administrator

 *

 */

publicclass Godown

{

    //总库存

    privateintmax = 100;

    //消费之后的库存数

    privateintcurNum = 0;

    public Godown()

    {

      

    }

    public Godown(int _curNum)

    {

       this.curNum = _curNum;

    }

   

    /**

     * 生产指定数量的产品

     * @param needNum

     */

    publicsynchronizedvoid produce(int needNum)

    {

       //如果需要生产的数量和当前结余的数量

       //之和大于总库存,则暂停生产

       while(needNum + curNum > max)

       {

           try

           {

              wait();

           }catch(InterruptedException e)

           {

              e.printStackTrace();

           }

       }

      

       curNum += needNum;

       System.out.println("已经生产了" + needNum + "个产品,现在仓库中有" + curNum + "个产品");

       //唤醒消费者进行消费

       notifyAll();

    }

   

    /**

     * 消费产品

     * @param consumNum  消费数

     */

    publicsynchronizedvoid consume(int consumNum)

    {

       //不能消费时,则等待生产者生产产品

       while(consumNum > curNum)

       {

           try

           {

              wait();

           } catch (InterruptedException e)

           {

              // TODO Auto-generatedcatch block

              e.printStackTrace();

           }

       }

      

       curNum -= consumNum;

       System.out.println("已经消费了" + consumNum + "个产品,现在仓库中有" + curNum + "个产品");

       notifyAll();

    }

   

   

}

 

 

 

/**

 * 生产者

 * @author Administrator

 *

 */

publicclass Produce extends Thread

{

    //仓库

    private Godown gd = null;

    //需要生产的数量

    privateintneedNum;

   

    public Produce(Godown _godown,int _needNum)

    {

       this.gd = _godown;

       this.needNum = _needNum;

    }

   

    @Override

    publicvoid run()

    {

       // TODO Auto-generatedmethod stub

//     super.run();

       //开始生产

       gd.produce(needNum);

    }

}

 

 

 

/**

 * 消费者

 * @author Administrator

 *

 */

publicclass Consumer extends Thread

{

    //仓库

    private Godown gd = null;

    //消费的数量

    privateintconsumNum = 0;

    public Consumer(Godown _gd,int _consumNum)

    {

       this.gd = _gd;

       this.consumNum = _consumNum;

    }

   

    @Override

    publicvoid run()

    {

       // TODO Auto-generatedmethod stub

//     super.run();

       gd.consume(consumNum);

    }

}

 

publicclass Test

{

    publicstaticvoid main(String[] args)

    {

       //初始库存10件产品

       Godown gd = new Godown(10);

      

       Produce pd = new Produce(gd,20);

       pd.start();

      

       Consumer cs = new Consumer(gd,60);

       cs.start();

      

       Produce pd2 = new Produce(gd,20);

       pd2.start();

      

       Produce pd3= new Produce(gd,20);

       pd3.start();

    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值