1、多线程概述
线程不是进程,它们都是并发机制的一种有效手段,进程包括线程,线程是比进程更小的执行单位,可以简单的将线程理解为任务。多线程就是指一个进程可以产生很多个更小的程序单元,它们可以同时存在,同时运行。
2、线程的实现
java实现线程主要是两种方式,一种是继承Thread类,另一种是实现Runnable接口。
public class Test {
public static void main(String[] args) {
Loop l=new Loop();
Thread t=new Thread(l);
t.start();//启动线程
}
}
//实现Runnable接口方式
class Loop implements Runnable{
@Override
public void run() {
for(int i=0;i<10;i++){
System.out.println("Loop:"+i+" "+new Date());
}
}
}
public class Test1 {
public static void main(String[] args) {
my t=new my("thread");//线程名称
t.start();//启动线程
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t.shut();//线程停止
System.out.println(Thread.currentThread().getName()+" is alive!");
}
}
//继承Thread类
class my extends Thread{
private boolean tag=true;
my(String s){
super(s);
}
public void run(){
while(Thread.currentThread().isAlive()&&tag){
try {
System.out.println(Thread.currentThread().getName()+" is start! "+new Date());
sleep(1000);
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName()+" is interrupted!");
e.printStackTrace();
return;
}
}
}
public void shut(){
System.out.println(this.getName()+" is dead!");
tag=false;
}
}
3、线程的状态
其实,java的main方法也是一个线程,而要想实现多线程,则必须在主线程中创建新的线程对象。任何线程一般具有5中状态,即创建、就绪、运行、阻塞、终止。
1)新建状态(New):新创建了一个线程对象。
2)就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。
3)运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。
4)阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。
5)死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
4、java中对线程的主要方法
1)设置和取得线程名称:Thread类的setName()和getName();
2)判断线程是否启动:isAlive()方法判断线程是否在活动
3)中断线程:首先通过isInterrupted()方法判断线程是否被中断,然后调用interrupt()方法中断线程
4)线程休眠:Thread类的sleep方法,并设置休眠的时间,单位是毫秒
5)线程优先级:多线程中,哪个线程的优先级高,哪个就先被执行,通过setPriority()方法来设置优先级,其中Thread类中有三个优先级常量(详见API文档)
6)线程礼让:yield方法是将一个线程的操作暂时让给其他线程执行
5、线程安全
在多线程中,线程之间很可能会共享某个类的属性,这样 就有可能出现同步和死锁的问题,这里不详细描述,这个时候我们可以通过synchronized关键字来将一个方法声明为同步方法。
下面这个例子就是解决线程操作中一个经典的案例--生产者和消费者,生产者不断生产产品,而消费者不断消费。
//商品类
class Production{
private String name;//名称
private int id;
private int num;//数量
public synchronized void add(int id,String name){
if(num!=0){//当数量大于0,则商品有剩余,需要被消费掉,故生产线程等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.id=id;
this.name=name;
num++;
System.out.println("生产一个产品:name="+name+",id="+id);
this.notifyAll();
}
public synchronized void delete(){
if(num==0){//当数量等于0,则商品没有剩余,需要生产,故消费线程等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
num--;
System.out.println("消费一个产品:name="+this.name+",id="+this.id);
this.notifyAll();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
//生产线程
class Producer implements Runnable{
private Production product;
public Producer(Production p){
this.product=p;
}
@Override
public void run() {
boolean flag=false;
for(int i=0;i<5;i++){
if(flag){
this.product.add(i, "hello");
flag=false;
}
else{
this.product.add(i, "test");
flag=true;
}
}
}
}
//消费线程
class Consumer implements Runnable{
private Production product;
public Consumer(Production p){
product=p;
}
@Override
public void run() {
for(int i=0;i<5;i++){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.product.delete();
}
}
}
public class ProducerAndConsumer {
public static void main(String[] args) {
Production p=new Production();
//共享同一个商品类
Producer producer=new Producer(p);
Consumer consumer=new Consumer(p);
//启动线程
new Thread(producer).start();
new Thread(consumer).start();
}
}
精彩科技工作室