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

Java多线程基础(一)

时间:2015-09-17 21:37:34      阅读:223      评论:0      收藏:0      [点我收藏+]

标签:

一、基本概念

线程状态图包括五种状态

技术分享

1、新建状态(New):线程对象被创建后,就进入新建状态。例如,Thread thread=new Thread();

2、就绪状态(Runnable):也被称为“可执行状态”。线程对象被创建后,其他线程调用了该对象的start()方法,从而来启动该线程。例如thread.start();处于就绪状态的线程,随时可能被CPU调度执行。

3、运行状态(Running):线程获取CPU权限进行执行。注意,线程只能从就绪状态进入到运行状态。

4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分为三种:

  (1)、等待阻塞:通过调用线程的wait()方法,让线程等待某个工作的完成。

  (2)、同步阻塞:线程在获取synchronized同步锁失败(因为锁被其他线程所占用),它会进入同步阻塞状态。

  (3)、其他阻塞:通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

5、死亡状态(Dead):线程执行完了,或者因异常退出了run()方法,该线程结束生命周期。

 二、实现多线程常用的两种方式:Thread和Runnable;【线程池(在java.util.concurrent包中)也可以实现多线程,后面讲解】

1、Thread和Runnable异同

  (1)相同点:都是“多线程的实现方式”。

  (2)不同点:Runnable是接口只包含一个Run()方法;实现方式可以定义一个类A实现该接口,通过new Thread(new A())等方式新建线程。Runnable接口代码如下:        

public interface Runnable {
    public abstract void run();
}

     Thread是实现了Runnable接口的一个类。如:public class Thread implements Runnable {}

     我们知道“一个类只能有一个父类,但却能实现多个接口”,因此Runnable具有更好的可扩展性。此外,Runnable还可以用于“资源的共享”。即,多个线程都是基于某

   一个Runnable对象建立的,它们会共享Runnable对象上建立的资源。通常建议通过Runnable实现多线程

2、Thread多线程示例

示例代码如下:

技术分享
import java.util.ArrayList;

public class MyThread extends Thread {
    private int ticket = 10;
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            if (this.ticket>0){
                System.out.println(this.getName()+"卖票:ticket"+this.ticket--);
            }
        }
    }
}

import org.junit.Test;

public class ThreadTest {
    @Test
    public void demo1() {
        //启动三个线程,t1,t2,t3;每个线程各卖十张票
        MyThread t1 = new MyThread();
        MyThread t2 = new MyThread();
        MyThread t3 = new MyThread();
        t1.start();
        t2.start();
        t3.start();
//        t1.run();
//        t2.run();
//        t3.run();
    }
}
Thread示例代码
技术分享
Thread-1卖票:ticket10
Thread-2卖票:ticket10
Thread-1卖票:ticket9
Thread-0卖票:ticket10
Thread-1卖票:ticket8
Thread-2卖票:ticket9
Thread-1卖票:ticket7
Thread-0卖票:ticket9
Thread-1卖票:ticket6
Thread-2卖票:ticket8
Thread-1卖票:ticket5
Thread-1卖票:ticket4
Thread-0卖票:ticket8
Thread-1卖票:ticket3
Thread-2卖票:ticket7
Thread-1卖票:ticket2
Thread-1卖票:ticket1
Thread-0卖票:ticket7
Thread-0卖票:ticket6
Thread-0卖票:ticket5
ThThread-0卖票:ticket4
运行结果

测试方法属于一个主线程,在里面创建了三个子线程,根据线程内安全,每个线程都会卖出10张票。

 

3、Runnable多线程示例

示例代码如下:

技术分享
package RunnableDemo;

public class MyThread implements Runnable {
    private int ticket = 10;

    public void run() {
        for (int i = 0; i < 20; i++) {
            if (this.ticket > 0) {
                System.out.println(Thread.currentThread().getName()+ "卖票:ticket" + this.ticket--);
            }
        }
    }
}


package RunnableDemo;

import ThreadDemo.ThreadTest;
import org.junit.Test;

public class RunnableTest {
    @Test
    public void demo1() {
        MyThread myThread = new MyThread();
        //启动三个线程t1,t2,t3(共用一个Runnable对象),这三个线程一共卖10张票
        Thread t1 = new Thread(myThread);
        Thread t2 = new Thread(myThread);
        Thread t3 = new Thread(myThread);
        t1.start();
        t2.start();
        t3.start();
    }
}
Runnable示例代码
技术分享
Thread-1卖票:ticket10
Thread-0卖票:ticket9
Thread-1卖票:ticket8
Thread-2卖票:ticket6
Thread-0卖票:ticket7
Thread-2卖票:ticket4
Thread-1卖票:ticket5
Thread-2卖票:ticket2
Thread-0卖票:ticket3
Thread-1卖票:ticket1
运行结果

主线程创建并启动了三个子线程,而且这三个子线程都是基于“myThread这个Runnable对象”而创建的。运行结果显示这三个线程共同卖出10张票,说明它们共享了Runnable接口。

4、Thread中start()和run()方法区别
(1)、run()方法属于主线程方法,可以当做普通方法使用,在主线程中按照顺序执行,不新开线程,当上一个run()方法体执行完后,下一个run()方法才可以继续,没有达到多线程的目的;

(2)、start()方法来启动线程,真正实现了多线程运行。start()方法启动线程后,线程处于就绪状态,并未运行。然后通过Thread类调用实现Thread类的run()方法,run()方法运行结束标志线程终止。在run()方法执行过程中,其他子线程无需等待某子线程run()方法执行完成,而是由CPU调度执行哪个子线程。start()方法不能被重复调用,否则会抛IllegalThreadStateException异常

也可以通过运行代码,查看当前运行线程名字来判断

技术分享
package StartVSRun;

public class MyThread extends Thread {
    public MyThread(String name) {
        super(name);
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+" is running");
    }
}


package StartVSRun;

import ThreadDemo.ThreadTest;
import org.junit.Test;

public class SVSR {
    @Test
    public void demo1() {
        Thread myThread = new MyThread("myThread");
        System.out.println(Thread.currentThread().getName() + " call myThread.run()");
        myThread.run();
        System.out.println(Thread.currentThread().getName() + " call myThread.start()");
        myThread.start();
    }
}
测试代码
技术分享
main call myThread.run()
main is running
main call myThread.start()
myThread is running
运行结果

 

Java多线程基础(一)

标签:

原文地址:http://www.cnblogs.com/hujiapeng/p/4814280.html

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