java多线程

一、多线程引入

通常来说cpu运行程序的速度是很快的,如果在某一时刻cpu只执行一个程序,这对于cpu资源来说是一种极大地浪费。而且随着多任务操作系统主导地位的确立,多线程的编程以不可或缺。

二、多线程概述

多线程是指在系统中同时有多条程序在并发的运行,虽然对于单核cpu来说,再某一时刻只有一条程序再运行,根本不可能实现“多条程序的同时运行”,但由于cpu的运行速度很快,在不断的快速切换中,用户感觉好像有多个程序在同时运行一样,这就是多线程的由来。

三、创建多线程的方法

1)直接继承Thread

步骤如下:

1,定义一个类继承Thread类。

2,覆盖Thread类中的run方法。

3,直接创建Thread的子类对象创建线程。

4,调用start方法开启线程并调用线程的任务run方法执行。

2)实现Runnable接口。

步骤如下:

1,定义类实现Runnable接口。

2,覆盖接口中的run方法,将线程的任务代码封装到run方法中。

3,通过Thread类创建线程对象,并将Runnable接口的子类对象作为Thread类的构造函数的参数进行传递。

4,调用线程对象的start方法开启线程。

四、两种创建线程方法的比较

实现Runnable接口的好处:

1,将线程的任务从线程的子类中分离出来,进行了单独的封装。

按照面向对象的思想将任务封装成对象。

2,避免了java单继承的局限性(如果用Thread的子类创建对象,它将不能再继承其它的类!)。

3.便于共享资源的操作。

五、runstart的特点

启动一个线程该调用start()方法而不能直接调用run()方法,这样不会创建一个新的线程,只是简单的在当前线程中执行了run()方法,当调用start()方法时,才会创建一个新的线程,这个新的线程将执行run()方法上的代码。
六、多线程的安全问题

线程安全问题产生的原因:

 

1,多个线程在操作共享的数据。

2,操作共享数据的线程代码有多条。

 

当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算。

就会导致线程安全问题的产生。

 

解决思路;

就是将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候,

其他线程时不可以参与运算的。

必须要当前线程把这些代码都执行完毕后,其他线程才可以参与运算。

 

java中,用同步代码块或者同步函数就可以解决这个问题。

 

同步代码块的格式:

synchronized(对象)

{

       需要被同步的代码;

}

 

同步的好处:解决了线程的安全问题。

同步的弊端:相对降低了效率,因为同步外的线程的都会判断同步锁。

同步的前提:同步中必须有多个线程并使用同一个锁。

 

同步函数的格式:

public synchronized void synchronized method()

{

……

}

同时要注意:同步非静态方法的监视器是this,而同步静态方法的监视器是当前所在的类的Class对象。只有线程用的是同一把锁时,才可以实现线程的同步。

一个多线程同步的示例程序如下:

class Ticket implements Runnable//extends Thread

{

       private  int num = 100;

 

       Object obj = new Object();

       public void run()

       {

              while(true)

              {

                     synchronized(obj)

                     {

                            if(num>0)

                            {

                                   try{Thread.sleep(10);}catch (InterruptedException e){}

                                  

                                   System.out.println(Thread.currentThread().getName()+".....sale...."+num--);

                            }

                     }

              }

       }

}

 

 

class  TicketDemo

{

       public static void main(String[] args)

       {

 

              Ticket t = new Ticket();//创建一个线程任务对象。

 

              Thread t1 = new Thread(t);

              Thread t2 = new Thread(t);

              Thread t3 = new Thread(t);

              Thread t4 = new Thread(t);

 

              t1.start();

              t2.start();

              t3.start();

              t4.start();

 

       }

}

七、多线程的死锁问题

在编写多线程同步的时候一定要注意避免死锁的发生。

Object o1=new Object();

Object o2=new Object();

 

while(true) {
 synchronized(o1) {
  ...

  synchronized(o2){
   ..

  }
  ...
 }
}

while(true) {
 synchronized(o2) {
  ...
  synchronized(o1){
   ...
  }
  ...
 }
}

八、线程间的通信问题

Object类里面有几个方法是用于线程通信的:wait()notify()notifyAll()。由于任何对象都可以作为监视器对象,所以任何对象都可以调用这几个方法。
但是这些方法只能在被synchronized修饰的方法或者代码块中调用。

九、停止线程

当要停止一个线程时一共有两个方法

停止线程:

1stop方法。

2run方法结束。

 

怎么控制线程的任务结束呢?

任务中都会有循环结构,只要控制住循环就可以结束任务。

控制循环通常就用定义标记来完成。

但是如果线程处于了冻结状态,无法读取标记。如何结束呢?

可以使用interrupt()方法将线程从冻结状态强制恢复到运行状态中来,让线程具备cpu的执行资格。

示例代码如下:

class StopThread implements Runnable

{

       private boolean flag = true;

       public synchronized void run()

       {

              while(flag)

              {

                     try

                     {

                            wait();//t0 t1

                     }

                     catch (InterruptedException e)

                     {

                            System.out.println(Thread.currentThread().getName()+"....."+e);

                            flag = false;

                     }

                    

                     System.out.println(Thread.currentThread().getName()+"......++++");

              }

       }

       public void setFlag()

       {

              flag = false;

       }

}

 

 

 

class StopThreadDemo

{

       public static void main(String[] args)

       {

              StopThread st = new StopThread();

 

              Thread t1 = new Thread(st);

              Thread t2 = new Thread(st);

 

              t1.start();

              t2.setDaemon(true);

              t2.start();

 

 

              int num = 1;

              for(;;)

              {

                     if(++num==50)

                     {

//                          st.setFlag();

                            t1.interrupt();

//                          t2.interrupt();

                            break;

                     }

                     System.out.println("main...."+num);

              }

 

              System.out.println("over");

       }

}

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值