Chinaunix首页 | 论坛 | 博客
  • 博客访问: 703816
  • 博文数量: 147
  • 博客积分: 6010
  • 博客等级: 准将
  • 技术积分: 1725
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-22 10:36
文章分类

全部博文(147)

文章存档

2011年(1)

2010年(1)

2009年(35)

2008年(110)

我的朋友

分类: Java

2008-09-16 23:10:16

 
一般来说进程就是在计算机中执行的程序,线程就是进程中的某个单一顺序的控制流
   线程不具备拥有系统资源的权利,实际上只具有运行必须的一些数据结构,父进程拥有的全部资源,可以被它所拥有的线程共享,线程可以创建线程,也可以撤销线程,从而实现程序的并发执行.
   多线程是同时存在若干个执行的实体线程,按照一定的规则共同工作.这里所谓的并发是在逻辑上的"同时",并不是物理上的同时.因为如果系统只有一个cpu,物理上的同时是不可能的.
   不同进程中的线程可以参加同一个cpu的调度,
   一个进程中的多个线程可以分部到多个处理器上运行.
   产生线程的时候继承原来线程的优先级,如果两个线程具有相同的优先级,这两个线程会被交替地运行.
线程的创建:
Java语言对多线程的支持通过类Thread和接口Runnable来实现。这里就不多说了。这里重点强调两个地方:
// 主线程其它代码段
ThreadClass subThread = new ThreadClass();
subThread.start();
// 主线程其它代码段
subThread.sleep(1000);

    有人认为以下的代码在调用start()方法后,肯定是先启动子线程,然后主线程继续执行。在调用sleep()方法后CPU什么都不做,就在那里等待休眠的时间结束。实际上这种理解是错误的。因为:

    ①start()方法的调用后并不是立即执行多线程代码,而是使得该线程变为可运行态(Runnable),什么时候运行是由操作系统决定的。

    ②Thread.sleep()方法调用目的是不让当前线程独自霸占该进程所获取的CPU资源,以留出一定时间给其他线程执行的机会(也就是靠内部自己协调)。

1.runnable接口只声明了run()方法

2.thread类声明并且实现了runnable接口,并且声明了许多用于创建管理和控制线程对象的方法

Thread()

Thread(String name)//指定线程名

Thread(Runnable target)//target指定线程的目标对象

Thread(Runnable target,String name)

一个线程对象的目标对象是指实现了Runnable接口的对象,目标对象为线程对象提供线程执行的run()方法,如果没有指定目标对象,则表明由线程对象本身提供线程执行的run方法

一个声明实现了runnable接口的类,其对象本身不是线程对象,同时还需要在声明线程对象。那么实现runnable接口的类对象是作为一个线程对象的目标对象来使用的
    继承Thread和实现Runnable接口.
    例子:public class SleepThread extends Thread{
public SleepThread(String name){
super(name);
}
public void run(){
try{
int sleepTime=(int)(Math.random()*100);
Thread.currentThread().sleep(sleepTime);
System.out.println(getName()+"休眠了"+sleepTime+"毫秒");
}catch(InterruptedException e){
e.printStackTrace();
}
}
public void static void main(String args[]){
Thread t1=new Thread(new SleepTime("线程1"));
Thread t2=new Thread(new SleepTime("线程2"));
Thread t3=new Thread(new SleepTime("线程3"));
t1.start();
t2.start();
t3.start();
}
}
结果:
线程3休眠了4妙
线程2休眠了34妙
线程1休眠了48妙
线程的状态:
BLOCKED  受阻塞并且在等待监听锁的某一线程的线程状态
NEW    至今没有启动的线程的状态
RUNNABLE  可运行的线程的状态
TERMINATED 已经终止的线程状态
TIMED_WAITING 具有指定等待时间的某一等待线程的线程状态
WAITING  某一等待线程的线程状态
getState()方法返回该线程的状态
isAlive()测试线程是否处于活动状态?如果线程已经启动尚未终止,则为活动状态.
public class ThreadStateDemo extends Thread{
public ThreadStateDemo(String str){
super(str);
}
public void run(){
State s=this.getState();
System.out.println(s);
System.out.println(getName()+"正在运行中....");
}
public static void mian(String args()){
ThreadStateDemo t=new ThreadStateDemo("线程");
State s=t.getState();
System.out.println(s);
t.start();
try{
t.join();//使当前线程强制等待该线程结束
}catch(InterruptedException e){
e....
}
}
}
结果:
NEW
RUNNABLE
线程运行中
TERMINATED
设定线程的优先级:
setPriority();
getPriority();
线程的让步:
yield():使当前线程让出cpu资源给其他线程
多线程的同步:
public class ThreadConDemo implements Runnable{
private int n=10;
public void run(){
for(int i=0;i<5;i++){
n-=i;
Thread.yield();
n+=i;
System.out.println(n);
}
}
public static void main(String args[]){
ThreadConDemo apple=new ThreadConDemo();
Thread thread1=new Thread(apple);
Thread thread2=new Thread(apple);
thread1.start();
thread2.start();
}
}
结果:
10
9
9
8
8
7
7
6
6
10
同步:
public class ThreadConDemo implements Runnable{
private int n=10;
public void run(){
synchronized(this){
for(int i=0;i<5;i++){
n-=i;
Thread.yield();
n+=i;
System.out.println(n);
}
}
}
public static void main(String args[]){
ThreadConDemo apple=new ThreadConDemo();
Thread thread1=new Thread(apple);
Thread thread2=new Thread(apple);
thread1.start();
thread2.start();
}
}
结果:
10
10
10
10
10
10
10
10
10
10
注解:当一个线程开始执行一个同步代码时,并不意味着这个线程不可以中断,正在执行同步代码的线程可以执行sleep方法进入休眠,但此时线程并没有释放同步资源.只是把cpu资源让给其他可运行的线程.
线程间的通信:
wait():通知当前的线程进入睡眠,知道其他线程进入调用notify()唤醒它
notify():唤醒在同步代码块中第一个调用wait方法的线程,
notifyAll():唤醒在该同步代码块中所有调用wait的线程,
线程组的概念暂时不说了!
线程的同步机制:

例子:银行帐户存取款的问题

public class Account{//帐户类

private String name;//存储姓名

private double balance;//余额

public Account(String name){

this.name=name;

}

public String getName(){

return name;

}

pbulic double balance(){

return balance;

}

public void put(double value){//存款

if(value>0)

  this.balance+=value;

}

public double get(double value){

if(value>0)

{

if(value<=balance)

  this.balance-=value;

else{

value=this.balance;

this.balance=0;

}

return value;

}

return 0;

}

}
 
 
class Save extends Thread{//存款线程
private Account account;
private double value;
 
public Save(double value){
this.account=account;
this.value=value;
}
 
public void run(){
synchronized(this.account){
double howmatch=this.account.balance();
this.account.put(this.value);
try{
sleep(1);
}catch(InterruptedException e){}
System.out.println(this.account.getName()+"帐户:现有“+howmatch+",存入"+this.value+",余额"+this.account.balance());
}
}
}
 
 
public class Fetch extends Thread{
private Account account;
private double value;
public Fetch(Account account,double value){
this.account=account;
this.value=value;
}
public void run(){
synchronized(this.account){
double hoematch=this.account.balance();
try{
sleep(1);
}catch(Exception e){}
System.out.println(this.account.getName()+"帐户:现有“+howmatch+",取走"+this.account.get(value)+",余额"+this.account.balance());
}
public static void main(String args[]){
Account wuxiaoxiao=new Account("wuxiaoxiao");
(new Save(wuxiaoxiao,100)).start();
(new Save(wuxiaoxiao,200)).start();
(new Fetch(wuxiaoxiao,300)).start();
}
}
由于多个线程共享同一个对象wuxiaoxiao,所以会出现问题!!!!若是
(new Save(wuxiaoxiao,100)).start();
(new Save(ranran,200)).start();
针对的是两个不同的用户就不会出现问题的!!!
改进就是在上面加上红色区域的部分!
线程互斥的实现
synchronized:声明一条语句和声明一个方法
同步语句:
synchronized(对象)
   语句
其中对象是多个线程共同操作的公共变量,即需要被锁定的临界资源,语句是临界区!
同步方法:
synchronized 方法声明
阅读(1005) | 评论(0) | 转发(0) |
0

上一篇:web service概述

下一篇:static和final修饰符

给主人留下些什么吧!~~