码迷,mamicode.com
首页 > 编程语言 > 详细

Java多线程理解

时间:2015-03-21 18:41:54      阅读:265      评论:0      收藏:0      [点我收藏+]

标签:java   多线程   thread   runnable   

Java实现多线程的两种方式分别是继承Thread类和实现Runnable接口。


代码示例:

class MyThread extends Thread{
 private String name;
 
 public MyThread(String name){
  this.name = name;
 }
 
 @Override 
  public void run(){
  for(int i=0;i<7;i++){
   System.out.println("线程开始:"+this.name+"次数"+i);
  }
 }
}
class MyRun implements Runnable{
 @Override
 public void run(){
  for(int i=0;i<7;i++){
   System.out.println("线程开始:"+Thread.currentThread().getName()+"次数"+i);
  }
 }
}
public class A{

 public static void main(String [] args){
 
  MyThread myThread = new MyThread("myThread");
  myThread.start();
 
  MyRun myRun = new MyRun();
  Thread run1 = new Thread(myRun, "myRun");
  run1.start();
 }
}
运行结果:
技术分享


关键点1:启动线程使用start()方法,使用run()方法并不会启动新线程。

public class A{

 public static void main(String [] args){
 
  MyThread myThread1 = new MyThread();
  myThread1.run();
 
  MyThread myThread2 = new MyThread();
  myThread2.run();
 }
} 
class MyThread extends Thread{
 public void run(){
  for(int i=0;i<7;i++){
   System.out.println("线程:"+Thread.currentThread().getName()+"次数"+i);
  }
 }
}

技术分享

start() : 通过调用start0()启动一个新线程,新线程会执行相应的run()方法。start()不能被重复调用。

run(): run()和普通的成员方法一样可重复调用。单独调用run()会在当前线程中执行run(),并不会启动新线程!


相关源码:

public synchronized void start() {
        if (threadStatus != 0)  //start()方法不能被重复调用,否则会抛出异常
            throw new IllegalThreadStateException();
        /* Notify the group that this thread is about to be started
         * so that it can be added to the group's list of threads
         * and the group's unstarted count can be decremented. */
        group.add(this);  //加入到线程组中
        boolean started = false;
        try {
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                /* do nothing. If start0 threw a Throwable then
                  it will be passed up the call stack */
            }
        }
    }
}
private native void start0();

@Override
public void run() { 
        if (target != null) {   //target是当前的Runnable对象
            target.run();
        }
    }

关键点2:Thread实现多线程与Runnable实现多线程的区别.

1、由于Java使用单继承,多接口实现原则,所以通过Runnable接口实现多线程更具灵活性;
2、Runnable对象可以被多个线程共享,适合于多个线程处理同一资源的情况。(不准确)

卖票问题:

1:Thread

class MyThread extends Thread{
 private int tickets =5;  
 @Override  
    public void run() {  
  while (tickets>0) {  
            tickets--;
            System.out.println(Thread.currentThread().getName()+"卖了一张票,剩余票数:"+tickets);  
       }
    }
}
public static void main(String [] args){
 
  MyThread myThread1 = new MyThread();
  myThread1.start();
 
  MyThread myThread2 = new MyThread();
  myThread2.start();
 }
技术分享

MyThread myThread1 = new MyThread();MyThread myThread2 = new MyThread();
因为每次都创建了新的MyThread对象,所以最后结果是卖了10张票;

2:Runnable
class MyThread extends Thread{
 private int tickets =5;  
 @Override  
    public void run() {  
  while (tickets>0) {  
            tickets--;
            System.out.println(Thread.currentThread().getName()+"卖了一张票,剩余票数:"+tickets);  
       }
    }
}
public static void main(String [] args){
 
  MyRunnable r = new MyRunnable();              
     Thread t1 = new Thread(r);  
     Thread t2 = new Thread(r);  
       
     t1.start();
     t2.start();  
 }
技术分享
MyRunnable对象只有一个,多线程共享同一对象,所以卖票结果好像是正确的。


关键点3:通过实现Runnable接口共享资源。

class MyRunnable implements Runnable{  
 
 private int tickets =10;  
    @Override  
    public void run() {  
     while (tickets>0) {  
             try {  
                Thread.sleep(100);  
             } catch (InterruptedException e) {  
                 e.printStackTrace();  
             }  
             tickets--;
             System.out.println(Thread.currentThread().getName()+"卖了一张票,剩余票数:"+tickets);  
        }  
     
    }  
} 
技术分享
显然最后剩余票数-1和-2是不正确的,所以仅仅实现Runnable接口是无法进行资源共享的,如果需要共享还是需要加入synchronized关键字。

class MyRunnable implements Runnable{  
 
 private int tickets =10;  
    @Override  
    public void run() {  
     synchronized(this){
      while (tickets>0) {  
                tickets--;
                System.out.println(Thread.currentThread().getName()+"卖了一张票,剩余票数:"+tickets);  
           }
     }
    }
}  
技术分享

Java多线程理解

标签:java   多线程   thread   runnable   

原文地址:http://blog.csdn.net/u013670933/article/details/44517115

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!