Java多线程

  在Java中,有两种实现多线程的方式:继承Thread类和实现Runnable接口。

 

Thread

此类的定义如下:

  public class Thread extends Object implments Runnable

构造方法如下:

  Thread(),Thread(Runnable target)  

静态字段:

  static int MAX_PRIORITY:线程可以具有的最高优先级

  static int MIN_PRIORITY:线程可以具有的最低优先级

  static int NORM_PRIORITY:分配给线程的默认优先级

主要方法:

  public void start():启动线程,Java虚拟机调用该线程的run方法。

  public static void sleep(long millis) throws InterruptedException:是线程休眠指定的毫秒

 

实例

package com.fuwh.thread;

public class ThreadTest01 {
    public static void main(String[] args) {
        System.out.println("线程最大优先级:"+Thread.MAX_PRIORITY);
        System.out.println("线程最小优先级:"+Thread.NORM_PRIORITY);
        System.out.println("线程默认优先级:"+Thread.MIN_PRIORITY);
        
        Thread t1=new Thread();
        Thread t2=new Thread("线程二");
        t1.setName("线程一");
        System.out.println(t1.getName()+"的优先级:"+t1.getPriority()+";Id:"+t1.getId());
        System.out.println(t2.getName()+"的优先级:"+t2.getPriority()+";Id:"+t2.getId());
    }
}
View Code

 

 实例2

 

package com.fuwh.thread;

class MyThread extends Thread{
    private String name;
    public MyThread(String name){
        this.name=name;
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i=0;i<10;i++){
            System.out.println(name+"线程运行  -- "+i);
        }
    }
}

public class ThreadTest02 {
    public static void main(String[] args) {
        MyThread mt1=new MyThread("线程一");
        MyThread mt2=new MyThread("线程二");
        mt1.start();
        mt2.start();
    }
}
View Code

此时的线程已经实现了交互的运行了。

 

Runnable接口

接口的定义如下:

  public interface Runnable

此类中只有一个run()方法。使用Runnable接口的对象创建线程的时候,启动该线程,就导致该独立执行的线程会调用该接口中的run()方法。

 

实例

 

package com.fuwh.thread;

class MyRunnable implements Runnable{
    private String name;
    public MyRunnable(String name){
        this.name=name;
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i=0;i<10;i++){
            System.out.println(name+"线程运行  -- "+i);
        }
    }
}

public class ThreadTest03 {
    public static void main(String[] args) {
        MyRunnable mt1=new MyRunnable("线程一");
        MyRunnable mt2=new MyRunnable("线程二");
        new Thread(mt1).start();
        new Thread(mt2).start();
    }
}
View Code

 

 

 

 

 那么,这两种实现方式有什么区别呢,首先,实现接口可以避免java单继承的问题,

其次,通过观察可以发现,如果以如下的方式启动多线程呢?

Runnable接口子类实例 ra=new Runnable接口子类实例 ();
new Thread(ra).start();
new Thread(ra).start();

则此时,两个线程在启动之后调用的都是ra实例的run方法,则可以达到资源共享的目的。

实例

 

package com.fuwh.thread;

class SellTicket implements Runnable{
    private int ticketCount=50;
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i=0;i<50;i++){
            if(this.ticketCount>0){
                System.out.println("售票一张,余票:"+this.ticketCount--);
            }
        }
    }
}

public class ThreadTest04 {
    public static void main(String[] args) {
        SellTicket st=new SellTicket();
        new Thread(st,"卖票点1").start();
        new Thread(st,"卖票点2").start();
    }
}
View Code

 

 

  但是,此时 仍然存在一个问题,倘若只剩最后一张票的时候,线程一去判断,还有一张票,于是准备去执行卖票,这时候线程二来了,发现也还有一张票,也准备去执行卖票,这时候,就会导致线程一和线程二都会去执行卖票操作,导致多卖一张票。

  这时候,就需要引入线程的同步和死锁概念。

同步与死锁

   在java中,要实现同步有两种方式:同步代码块同步方法

同步代码块修改上述实例: 

 

package com.fuwh.thread;

class SellTicket implements Runnable{
    private int ticketCount=10;
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i=0;i<50;i++){
            synchronized (this) {
                if(this.ticketCount>0){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.println("售票一张,余票:"+this.ticketCount--);
                }
            }
        }
    }
}

public class ThreadTest04 {
    public static void main(String[] args) {
        SellTicket st=new SellTicket();
        new Thread(st,"卖票点1").start();
        new Thread(st,"卖票点2").start();
    }
}
View Code

 

 同步方法修改:

 

package com.fuwh.thread;

class SellTicket implements Runnable{
    private int ticketCount=10;
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i=0;i<50;i++){
            this.sellTicket();
        }
    }
    public  synchronized void sellTicket(){
        if(this.ticketCount>0){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("售票一张,余票:"+this.ticketCount--);
        }
    }
}

public class ThreadTest06 {
    public static void main(String[] args) {
        SellTicket st=new SellTicket();
        new Thread(st,"卖票点1").start();
        new Thread(st,"卖票点2").start();
    }
}
View Code

 

 

 死锁

   死锁就是说当两个线程在互相等待的时候,就会出现死锁。

 

posted @ 2017-03-02 22:29  Ouka傅  阅读(164)  评论(0编辑  收藏  举报