Java线程的概念与原理
 

2010-03-03 来源:网络

 

一、操作系统中线程和进程的概念

现在的操作系统是多任务操作系统。多线程是实现多任务的一种方式。

进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程中可以启动多个线程。比如在Windows系统中,一个运行的exe就是一个进程。线程是指进程中的一个执行流程,一个进程中可以运行多个线程。比如java.exe进程中可以运行很多线程。线程总是属于某个进程,进程中的多个线程共享进程的内存。“同时”执行是人的感觉,在线程之间实际上轮换执行。

二、Java中的线程

在Java中,“线程”指两件不同的事情:

1、java.lang.Thread类的一个实例;

2、线程的执行。

使用java.lang.Thread类或者java.lang.Runnable接口编写代码来定义、实例化和启动新线程。一个Thread类实例只是一个对象,像Java中的任何其他对象一样,具有变量和方法,生死于堆上。Java中,每个线程都有一个调用栈,即使不在程序中创建任何新的线程,线程也在后台运行着。一个Java应用总是从main()方法开始运行,mian()方法运行在一个线程内,它被称为主线程。一旦创建一个新的线程,就产生一个新的调用栈。线程总体分两类:用户线程和守候线程。

当所有用户线程执行完毕的时候,JVM自动关闭。但是守候线程却不独立于JVM,守候线程一般是由操作系统或者用户自己创建的。

———————————MultiT.java——————————————————————

class MultiThread

{

public static void main(String[] args)

{

MyThread mt=new MyThread();

//mt.setDaemon(true);//设定为后台线程,main进程结束时,后台进程也跟着结束

//mt.setPriority(Thread.MAX_PRIORITY); //设定线程优先级,MAX_PRIORITY为10,MIN_PRIORITY为1,NORM_PRIORITY为5。

//设定为最高优先级后,程序运行时,mt线程一直运行,强制终止时,main线程才运行

//设定为最高优先级的线程,无论有无yield();,线程总一直运行,直到强制终止时,main和mt线程交替运行

mt.start();

int index=0;

while(true) //显示结果与教程不同

{

if(index++==100)

break;

System.out.println("main:"+Thread.currentThread().getName()); //获取线程名字

}

}

}

class MyThread extends Thread

{

public void run()

{

while(true)

{

System.out.println(getName());

yield(); //允许当前线程停止,转去执行其他线程,静态方法

//mt进程执行时,切换到main进程,main进程执行一段时间后,

//切换进程到mt,mt执行完获取名字后,返回到main进程

}

}

}

//一个长时间处于等待状态的线程也有可能被线程调度器调度,从而运行,

//打破高优先级线程始终获有运行时间的状态

——————————————————————————————————————

——————————MultiThread.java———————————————————————

class MultiThread

{

public static void main(String[] args)

{

MyThread mt=new MyThread();

//new Thread(mt).start(); //创建多个同样的线程访问同一个变量index,若MyThread采用继承Thread方式,则无法共享同一个变量

//new Thread(mt).start();

//new Thread(mt).start();

//new Thread(mt).start();

mt.getThread().start(); //也可以采用内部类的方式共享访问同一个变量

mt.getThread().start();

mt.getThread().start();

mt.getThread().start();

//mt.setDaemon(true);//设定为后台线程,main进程结束时,后台进程也跟着结束

//mt.setPriority(Thread.MAX_PRIORITY); //设定线程优先级,MAX_PRIORITY为10,MIN_PRIORITY为1,NORM_PRIORITY为5。

//设定为最高优先级后,程序运行时,mt线程一直运行,强制终止时,main线程才运行

//设定为最高优先级的线程,无论有无yield();,线程总一直运行,直到强制终止时,main和mt线程交替运行

//mt.start();

int index=0;

while(true) //显示结果与教程不同

{

// if(index++==100)

// break;

System.out.println("main:"+Thread.currentThread().getName()); //获取线程名字

}

}

}

class MyThread //implements Runnable //extends Thread //使用外部类的方式

//使用内部类完成使用Runnable接口才能完成的两个功能 a,创建多个线程.b,访问同一个变量

{

int index=0;

private class InnerThread extends Thread //不想让外部访问其实现方法,加上private

{

public void run()

{

while(true)

{

System.out.println(Thread.currentThread().getName()+":"+index++);

}

}

}

Thread getThread()

{

return new InnerThread();

}

/*

public void run()

{

while(true)

{

System.out.println(Thread.currentThread().getName()+":"+index++);

//yield(); //允许当前线程停止,转去执行其他线程,静态方法

//mt进程执行时,切换到main进程,main进程执行一段时间后,

//切换进程到mt,mt执行完获取名字后,返回到main进程

}

}

*/

}

//一个长时间处于等待状态的线程也有可能被线程调度器调度,从而运行,

//打破高优先级线程始终获有运行时间的状态

//如果不需要修改Thread类的除了run方法外的其他方法,选用implements Runnable.

———————————————————————————————————————

———————————TicketsSystem.java———————————————————

//多线程实现火车票的售票系统 .用同步块,或着同步方法

class TicketsSystem

{

public static void main(String[] args) //运行结果与教程中不同,不完全顺序,每次运行,顺序都不完全一样

{

SellThread st=new SellThread();//创建四个线程访问同一变量tickets.

// 错 SellThread st1=new SellThread();//若采用创建四个对象的方式,则每个对象中都有100张票

new Thread(st).start(); //b为false,用的同步方法 | //同步方法与同步块共用中,显示的是只调用了同步块,而同步方法未被调用

//b为true,用的同步块, | //原因,启动第一个线程后,CPU时间片没有到期,线程没有立即运行,接着执行b=true,

// | //解决办法,启动第一个线程后,执行一个睡眠时间,让CPU时间片到期

try

{

Thread.sleep(1);

}

catch(Exception e)

{

e.printStackTrace();

}

st.b=true;

new Thread(st).start();

//new Thread(st).start();

//new Thread(st).start();

}

}

class SellThread implements Runnable //程序有点小问题,当剩下最后一张票时,四个线程都运行,可能会出现票数为0,-1,-2。(系统长时间运行时)

//可加上一个静态方法sleep();它会抛出异常

{

int tickets=100;

//Object obj=new Object();//也可以声明一个Thread对象

Thread th=new Thread();

boolean b=false;

public void run()

{

if(b==false)

{

while(true)

sell();

}

else

{

while(true)

{ //同步方法利用的是this所代表的对象的锁

synchronized(this) //采用同步后,显示正确。此方法两步,1,声明Thread对象,2,用synchronized把原方法括起来

{ //这里换th为this

///*

if(tickets>0)

{

try

{

Thread.sleep(0);

}

catch(Exception e)

{

e.printStackTrace();

}

System.out.println("th "+Thread.currentThread().getName()+" sell tickets:"+tickets);

tickets--;

}

//*/

}

}

}

}

public synchronized void sell() //每个class也有一个锁,是这个class所对应的class对象的锁(监视器)

{

if(tickets>0)

{

try

{

Thread.sleep(1);

}

catch(Exception e)

{

e.printStackTrace();

}

System.out.println("sell "+Thread.currentThread().getName()+" sell tickets:"+tickets);

tickets--;

}

}

}

————————————————————————————————————————

———————————TestWN.java————————————————————

class Test

{

public static void main(String[] args)

{

Queue q=new Queue();

Producer p=new Producer(q);

Consumer c=new Consumer(q);

p.start();

c.start();

}

}

class Producer extends Thread

{

Queue q;

Producer(Queue q)

{

this.q=q;

}

public void run()

{

for(int i=0;i<10;i++)

{

q.put(i);

System.out.println("Producer put: "+i);

}

}

}

class Consumer extends Thread

{

Queue q;

Consumer(Queue q)

{

this.q=q;

}

public void run()

{

while(true)

{

System.out.println("Consumer get: "+q.get());

}

}

}

class Queue //wait,notify,方法必须用在同步方法中,要加上关键字synchronized

{

int value;

boolean bFull=false;

public synchronized void put(int i)

{

if(!bFull)

{

value=i;

bFull=true;

notify();

}

try

{

wait();

}

catch(Exception e)

{

e.printStackTrace();

}

}

public synchronized int get()

{

if(!bFull)

{

try

{

wait();

}

catch(Exception e)

{

e.printStackTrace();

}

}

bFull=false;

notify();

return value;

}

}

————————————————————————————————————

————————————TestThread.java———————————————————————

class TestThread

{

public static void main(String[] args)

{

Thread1 t1=new Thread1();

t1.start();

int index=0;

while(true)

{

if(index++==500)

{

t1.stopThread();

t1.interrupt(); //让线程1终止

break;

}

System.out.println(Thread.currentThread().getName());

}

System.out.println("main() exit");

}

}

class Thread1 extends Thread

{

private boolean bStop=false;

public synchronized void run()

{

while(!bStop)

{

try

{

wait(); //加入wait后,main线程结束时,程序还未终止,原因是Thread1的线程调用wait方法,进入对象的等待队列中,需要notify方法将它唤醒

}

catch(Exception e)

{

//e.printStackTrace();

if(bStop)

return;

}

System.out.println(getName());

}

}

public void stopThread()

{

bStop=true;

}

}

——————————————————————————————————————



Java 中的中文编码问题
Java基础知识的三十个经典问答
玩转 Java Web 应用开发
使用Spring更好地处理Struts
用Eclipse开发iPhone Web应用
插件系统框架分析
更多...   


Struts+Spring+Hibernate
基于J2EE的Web 2.0应用开发
J2EE设计模式和性能调优
Java EE 5企业级架构设计
Java单元测试方法与技术
Java编程方法与技术


Struts+Spring+Hibernate/EJB+性能优化
华夏基金 ActiveMQ 原理与管理
某民航公司 Java基础编程到应用开发
某风电公司 Java 应用开发平台与迁移
日照港 J2EE应用开发技术框架与实践
某跨国公司 工作流管理JBPM
东方航空公司 高级J2EE及其前沿技术
更多...   
 
 
 
 

组织简介 | 联系我们 |   Copyright 2002 ®  UML软件工程组织 京ICP备10020922号

京公海网安备110108001071号