Android 学习系列 - Java 多线程

Java 多线程

Thread

sample

class MyThread extends Thread {

private String name;public MyThread(String name) {    this.name = name;}@Overridepublic void run() {    //.....}

}

class Main {
public static void main(String[] args) {
MyThread a = new MyThread('A');
MyThread b = new MyThread('B');
a.start();
b.start();
}
}
start 方法不能重复调用, 重复调用会出现java.lang.IllegalThreadStateException异常

Runnable

sample

class MyRunnable extend Runnable{
public MyRunnable() {

}@Overridepublic void run() {}

}

class Main {
public static void main(String[] args) {
MyRunnable a = new MyRunnable('A');
MyRunnable b = new MyRunnable('B');

    Thread demoa = new Thread(a);    Thread demob = new Thread(b);    demoa.start();    demob.start();}

}

关于选择继承Thread还是实现Runnable接口?

其实Thread也是实现Runnable接口的:

class Thread implements Runnable {
//…
public void run() {
if (target != null) {
target.run();
}
}
}

Thread中的run方法调用的是Runnable接口的run方法。Thread和Runnable都实现了run方法,这种操作模式其实就是代理模式。

Thread和Runnable的区别

如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。

class MyThread implements Runnable{

private int ticket = 5;  //5张票public void run() {    for (int i=0; i 0) {            System.out.println(Thread.currentThread().getName()+ "正在卖票"+this.ticket--);        }    }}

}
public class lzwCode {

public static void main(String [] args) {    MyThread my = new MyThread();    new Thread(my, "1号窗口").start();    new Thread(my, "2号窗口").start();    new Thread(my, "3号窗口").start();}

}
实现Runnable接口比继承Thread类所具有的优势:

1):适合多个相同的程序代码的线程去处理同一个资源
2):可以避免java中的单继承的限制
3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立。

主线程和子线程之间的关系

在java中,每次程序运行至少启动2个线程。一个是main线程,一个是垃圾收集线程。因为每当使用java命令执行一个类的时候,实际上都会启动一个JVM,每一个jVM就是在操作系统中启动了一个进程。

主线程也有可能在子线程结束之前结束。并且子线程不受影响,不会因为主线程的结束而结束。

// 休眠两秒Thread.sleep(2000);// 强制加入thread.join();// 后台线程thread.setDaemon(true);/  * @author Rollen-Holt 后台线程 * */class hello implements Runnable {    // 虽然有一个死循环,但是程序还是可以执行完的。因为在死循环中的线程操作已经设置为后台运行了。    public void run() {        while (true) {            System.out.println(Thread.currentThread().getName() + "在运行");        }    }    public static void main(String[] args) {        hello he = new hello();        Thread demo = new Thread(he, "线程");        demo.setDaemon(true);        demo.start();    }}// 优先级// 不要误以为优先级越高就先执行。谁先执行还是取决于谁先去的CPU的资源。thread.setPriority(8);// 礼让// 在线程操作中,也可以使用yield()方法,将一个线程的操作暂时交给其他线程执行。Thread.currentThread().yield();

同步和死锁

/

  • @author Rollen-Holt

  • */
    class hello implements Runnable {
    public void run() {
    for(int i=0;i0){
    try{
    Thread.sleep(1000);
    }catch(InterruptedException e){
    e.printStackTrace();
    }
    System.out.println(count--);
    }
    }
    }

    public static void main(String[] args) {
    hello he=new hello();
    Thread h1=new Thread(he);
    Thread h2=new Thread(he);
    Thread h3=new Thread(he);
    h1.start();
    h2.start();
    h3.start();
    }
    private int count=5;
    }

//【运行结果】:
// 5

// 4

// 3

// 2

// 1

// 0

// -1
这里出现了-1,显然这个是错的。应该票数不能为负值。
如果想解决这种问题,就需要使用同步。所谓同步就是在统一时间段中只有有一个线程运行,其他的线程必须等到这个线程结束之后才能继续执行。

使用线程同步解决问题

使用同步代码块和同步方法

同步代码块

synchronized(同步对象){    //需要同步的代码}

/

  • @author Rollen-Holt

  • */
    class hello implements Runnable {
    public void run() {
    for(int i=0;i0){
    try{
    Thread.sleep(1000);
    }catch(InterruptedException e){
    e.printStackTrace();
    }
    System.out.println(count--);
    }
    }
    }
    }

    public static void main(String[] args) {
    hello he=new hello();
    Thread h1=new Thread(he);
    Thread h2=new Thread(he);
    Thread h3=new Thread(he);
    h1.start();
    h2.start();
    h3.start();
    }
    private int count=5;
    }

    同步方法

    synchronized 方法返回类型方法名(参数列表){

    // 其他代码

}
/

  • @author Rollen-Holt

  • */
    class hello implements Runnable {
    public void run() {
    for (int i = 0; i 0) {
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println(count--);
    }
    }

    public static void main(String[] args) {
    hello he = new hello();
    Thread h1 = new Thread(he);
    Thread h2 = new Thread(he);
    Thread h3 = new Thread(he);
    h1.start();
    h2.start();
    h3.start();
    }

    private int count = 5;
    }

    死锁

    当多个线程共享一个资源的时候需要进行同步,但是过多的同步可能导致死锁。

生产者,消费者问题

/
面包类,用于存放厨师生产的面包
*/
public class Bread {
private String producer;

public Bread(String producer) {    super();    this.producer = producer;}@Overridepublic String toString() {    return producer;}

}

/*

  • 篮子类,用于存放面包

  • 篮子假定最多放10个面包
    */
    public class Basket {
    private int index = 0;
    private Bread[] arrayBread = new Bread[10];

    /*

    • 此方法用于往篮子里扔面包 每当厨师生成好一个面包就往篮子里边扔 由于当某一个厨师在往篮子扔面包的过程(还没扔完,但是面包已经在篮子里),

    • 又有一个厨师要往篮子里扔面包。 如果这是篮子里已经有9个面包的话,最后一个厨师就不能在扔了。

    • 所以需要给这个方法加把锁,等一个厨师扔完后,另外一个厨师才能往篮子里扔。
      */
      public synchronized void push(int id, Bread bread) {
      System.out.println("生成前篮子里有面包:" + index + " 个");
      // 当厨师发现篮子满了,就在那里不停的等着
      while (index == arrayBread.length) {
      System.out.println("篮子满了,我开始等等。。。。。。");
      try {
      // 厨师(一个生产线程)开始不停等待
      // 他需要等待顾客(一个消费线程)把它叫醒
      this.wait();
      } catch (InterruptedException e) {
      e.printStackTrace();
      }
      }

      // 唤醒一个正在等待的线程,如果唤醒的线程为生产线程,则又会进入等待状态,
      // 如果为消费线程,则因生产线程生产了面包的缘故,消费线程可以进行消费
      this.notify();
      arrayBread[index] = bread;
      index++;
      System.out.println(bread);

    }

    /*

    • 此方法用于往篮子里拿面包 加锁原因和上边一样
      */
      public synchronized Bread pop(int id) {
      System.out.println("消费前篮子里有面包:" + index + " 个");
      while (index == 0) {
      System.out.println("篮子空了,我开始等等。。。。。。");
      try {
      // 顾客(一个消费线程)开始不停等待
      // 他需要等待厨师(一个生产线程)把它叫醒
      this.wait();
      } catch (InterruptedException e) {
      e.printStackTrace();
      }
      }

      // 唤醒一个正在等待的线程,如果唤醒的线程为消费线程,则又会进入等待状态,
      // 如果为生产线程,则因生产线程消费了面包的缘故,生产线程可以进行生产
      this.notify();
      index--;
      System.out.println("第" + id + "个顾客消费了 -->" + arrayBread[index]);
      return arrayBread[index];
      }
      }

/*

  • 厨师类,用于生产面包
    */
    public class Kitchener implements Runnable {
    private Basket basket;
    private int id;

    public Kitchener(int id,Basket basket) {
    super();
    this.id = id;
    this.basket = basket;
    }

    @Override
    public void run() {
    //让厨师生产10个面包
    for (int i = 1; i
    名字和年龄对应错误了,

http://www.cnblogs.com/rollenholt/archive/2011/08/28/2156357.html

关键字:产品经理

版权声明

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处。如若内容有涉嫌抄袭侵权/违法违规/事实不符,请点击 举报 进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部