java 多线程
线程的基本概念:
线程是一个程序里面不同的执行路径;(省略了具体操作系统关于线程的概念)
进程和线程的区别:
每个进程都有独立的代码和数据空间(进程上下文),进程切换要消耗较多的系统资源;
线程可以看成是轻量级的进程,同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(pc)线程切换消耗的系统资源小!
java中的线程的创建与启动:
1.定义线程类实现Runnable接口:
//创建多线程的小例子(实现Runnable)接口
public class TestThread1
{
public static void main(String args[])
{
Runner1 r = new Runner1();
//new一个Runner1对象,
Thread t = new Thread(r);
//new一个线程对象,并将我们的Runner1传进去,线程开始创建
t.start();
//启动一个新线程t;
for(int i=0; i<100; i++)
{
System.out.println("Main Thread:------" + i);
}
}
}
//实现Runnable接口;
class Runner1 implements Runnable {
//重写run()方法,加入我们要执行的代码;
public void run() {
for(int i=0; i<100; i++) {
System.out.println("Runner1 :" + i);
}
}
}
2.从Thread继承:
public class TestThread1 {
public static void main(String args[]) {
Runner1 r = new Runner1();
r.start();
//线程启动;
for(int i=0; i<100; i++) {
System.out.println("Main Thread:------" + i);
}
}
}
class Runner1 extends Thread {
public void run() {
for(int i=0; i<100; i++) {
System.out.println("Runner1 :" + i);
}
}
}
一般情况下我们都用第一种方法,实现Runner接口;这样可以带来程序的灵活性;
线程控制的基本方法:
isAlive()
//判断线程是否还"活"着
static Thread currentThread()
//返回对当前正在执行的线程对象的引用(返回现在执行的线程);
getPriority()
//获得线程优先级数值1-10(默认为5);
setPriority()
//设置线程优先级1-10(默认为5);
/*线程常量
static int MAX_PRIORITY
线程可以具有的最高优先级。
static int MIN_PRIORITY
线程可以具有的最低优先级。
static int NORM_PRIORITY
分配给线程的默认优先级
*/
String getName()
//返回该线程的名称
static void sleep(long millis) throws InterruptedException
//在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响
static void join() throws InterruptedException
//调用某线程的该方法,将当前线程于该线程"合并",既等待该线程结束,再恢复当前线程运行(合并线程);
static void yield()
//暂停当前正在执行的线程对象,并执行其他线程,让出CPU给其他人用。void wait() throws InterruptedException
//在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。
换句话说,如果没有notify()或者notifyAll()唤醒wait(),那么该对象将一直sleep(但是sleep和wait也是有区别的);
void notify() 和 void notifyAll()
//唤醒在此对象监视器上等待的单个和多个线程,前者唤醒一个,后者唤醒全部;
线程同步:
synchronized(锁定对象);
1、synchronized关键字的作用域有二种:
1)是某个对象实例内,synchronized aMethod(){}可以防止多个线程同时访问这个对象的synchronized方法(如果一个对象有多个synchronized方法,只要一个线程访问了其中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法)。这时,不同的对象实例的 synchronized方法是不相干扰的。也就是说,其它线程照样可以同时访问相同类的另一个对象实例中的synchronized方法;
2)是某个类的范围,synchronized static aStaticMethod{}防止多个线程同时访问这个类中的synchronized static 方法。它可以对类的所有对象实例起作用。
2、除了方法前用synchronized关键字,synchronized关键字还可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问。用法是: synchronized(this){/*区块*/},它的作用域是当前对象;
3、synchronized关键字是不能继承的,也就是说,基类的方法synchronized f(){} 在继承类中并不自动是synchronized f(){},而是变成了f(){}。继承类需要你显式的指定它的某个方法为synchronized方法;
关于synchronized关键字的说明转载自:http://www.learndiary.com/archives/diaries/2910.htm
wait和sleep的区别:
自版本1.0开始,J2SE就提供了wait,notify以及notifyAll方法。本文就对这三个方法进行介绍,并进行一定的分析,最后给出本人觉有问题的地方,希望对大家有所启发。
虽然以上所说的三个方法最常出现的地方是线程的内部,但是并不意味这这些方法是Thread类的成员函数。实际上java在设计的时候就充分考虑到了同步的问题,因而在设计基础类 Object的时候就为其提供了这三个函数。这就意味着你所编写的任何类都可以使用这些方法(当然某些时候这些方法是没有意义的)。
按照上面的说法,你肯定有这样的疑惑:既然是跟对象有关系,那为什么我看见的程序中,最常见的使用是在线程里呢?以下我就将这个问题给出答案!
首先,我们要知道wait()跟sleep()本质上来说是绝对不一样的。
sleep()使得一个进程进入睡眠状态,但是线程所占有的资源并没有释放。比如,你在synchronized模块(加函数锁或者对象锁)里面调用了sleep(),虽然线程睡着了而且没有使用资源,但是它依然保存着锁,别的线程依然无法调用相关的synchronized模块。
而wait()就不同,它实际上了放弃了锁,将资源贡献出来,而使自己暂时离岗。这个离岗状态一直会持续到“boss“(其他的线程)调用了notify(),通知线程继续回来工作。如果你对程序框架很熟悉的话,你肯定会想到wait()和 notify()的巨大作用了!!!如果你的程序不是玩具的话,你可能都需要使用到这三个函数。
当前的程序大多数都是多线程的,不同的线程对应着不同功能。设计良好的软件,能够使用户在程序运行的时候,对软件的功能进行增肥和瘦身。按照笨办法,我们可以用个while不断的判断某一标志,来识别用户是否启动了某项功能。
这样一来while语句的执行占用了cpu的周期,降低了性能。如果我们使用wait(),当我们需要使用某项功能的时候,只需要用 notify将进程”上岗“。 java里面具体怎么做的,我们不得而知,但是我们可以推断——jre肯定在开辟了一定的空间来存放信息,使得notify找到中断位置,让线程继续运行!这可是典型的用空间换时间哟!!!值得一提的是线程里面的同步就是对这三个方法的应用!
以下我将给出我自己编写的程序,说明怎么样用这三个方法(绝对原创哟!!!):
文件1:WaitSyn.java
import java.lang.Thread;
import java.lang.InterruptedException;
//线程类
public class WaitSyn extends Thread
{
public void run(){
waitting();
}
//加锁的方法waitting
public synchronized void waitting(){
try{
System.out.println("Waitting");
wait();
System.out.println("Bingle");
}
catch(InterruptedException e){
e.printStackTrace();
}
} //Method exit
public void callup(){
synchronized(this){
System.out.println("In the callup()");
notifyAll();
}
} //Method exit
} //WaitSyn exit
/*文件2:CallSyn.java */
import java.lang.Thread;
//线程类
public class CallSyn extends Thread{
WaitSyn waitSyn;
public CallSyn(WaitSyn input){
waitSyn = input;
}
public void run(){
waitSyn.callup();
System.out.println("In the ClassSyn");
}
} //CallSyn exit
//文件3:Test.java
import java.lang.InterruptedException;
public class Test{
public static void main(String arg[]){
WaitSyn waitSyn = new WaitSyn();
waitSyn.start();
CallSyn callSyn = new CallSyn(waitSyn);
callSyn.start();
}
} //Main exit
wait和sleep的区别转载自http://dev.csdn.net/Develop/article/28/55640.shtm