线程:是程序内部的顺序控制流。
Java线程:通过java.lang.Thread类来实现。
一、实现线程方法:
1、新建一个Thread对象
2、新建一个Thread类的子类对象
3、新建一个实现Runnable接口的对象
二、Java VM的主线程:VM启动一个主线程(由public static void main(String[] args){}定义)。
多线程:在操作系统中同时运行几个线程(顺序流)。即程序运行期间多个进程(主方法、其他进程实现方法的实例对象)之间共享CPU。
三、线程的状态:
1、创建:创建线程对象。
2、start:调用线程对象的该方法,则该线程进入就绪状态
3、就绪:就绪状态的线程,等待CPU的调度,调度后执行。
4、运行:就绪状态获取CPU资源,线程就可以执行
5、阻塞:阻塞事件发生触发线程从运行状态进入阻塞状态。当阻塞解除后线程进入就绪状态。阻塞事件例同步方法中调用this.wait()方法,阻塞当前锁定该对象的线程。阻塞解除事件如notify/notifyAll来唤醒wait进程。注wait方法在wait pool中不占用锁,唤醒后重新占用锁,而sleep在休眠时也占用锁。
6、终止:销毁线程。原来的JDK中使用stop方法来销毁线程。在JDK6中已经停用了改方法。现在一般处理方法是要终止线程,即线程的run方法运行完毕。可设置一个boolean flag属性来控制run方法的执行,当且仅当flag为true,run方法内部才执行。同时,可以定义一个shutDown方法来利用修改flag为false来终止线程的运行。
如:定义一个线程类
class TreadStop implements Runnable {
private boolean flag=true;
public void run() {
int i = 0;
while (flag==true) {
System.out.print("Thread of ThreadStop: " + i++);
}
}
public void shutDown() {
flag = false;
}
}
在调用该线程类的一个实例时:使用实例调用shutDown方法类终止线程
public class TestThreadStop{
public static void main(String args[]){
ThreadStop t = new ThreadStop();
t.start();
for(int i=0;i<100000;i++){
if(i%10000==0 & i>0)
System.out.println("in thread main i=" + i);
}
System.out.println("Thread main is over");
t.shutDown();
}
}
四、线程状态控制方法:
方法名 |
控制说明 |
isAlive |
线程是否启动并未终止 |
getPriority() |
获取线程的调度优先级数值。优先级高的占用CPU时间片多。 |
setPriority() |
设置线程的调度优先级数值。数值为1-10,默认为5。 |
Thread.sleep() |
当前线程睡眠的毫秒数 |
join() |
调用某个线程的该方法,将当前进程和该进程合并,直到该进程终止,再恢复当前进程的运行
相当于方法调用
|
yeild |
让出CPU,进入就绪状态等待调度 |
wait |
进入对象的wait pool |
notify/notifyAll |
唤醒对象的wait pool的一个或全部线程 |
注;wait和sleep的区别:
wait是别的线程可以访问锁定对象,且调用wait方法时必须锁定该对象。而sleep时别的线程也不可以访问锁定对象。
五、线程同步:
在Java中,用对象互斥锁来保证共享数据的完整性。每个对象都对应一个“互斥锁”标记。这个标记保证在任意时刻,只有一个线程在访问该对象。Java中,互斥锁标记用Synchronized关键字来说明。当某个对象用Synchronized修饰时表示任一时刻只有一个线程可以访问该对象,这样保证了数据的完整性。同样,Synchronized可以用于修饰方法,说明该方法是同步方法(方法执行时当前对象被锁定)。
synchronized (this){ //执行语句块时当前对象被锁定 }
同理同步方法为:
public synchronized void methodName(){ //执行该方法时当前对象被锁定 }
否则,在多个线程运行时不能保证原来一个语句块的原子性:
例:我们希望在add方法中输出该方法是被第几次访问。
public static int num=0;
public void add(){
num++;
System.out.println("这是第 "+num+"次调用该方法");
}
在进程1中:在num++;和System.out.println();之间若没有锁定当前对象的话,其他进程(进程2)打断当前进程(进程1)的执行,执行了add方法中的num++,此时num值为2。然后回到原来的进程1 执行,输出进程1是第2次调用该方法。然后回到进程2,输出这是第二次调用该方法。这就导致执行结果和我们预期的不一致。
这就是为什么要用synchronized关键字来锁定当前对象。若锁定在方法add中当前对象或使用synchronized(this){}将要原子执行的语句放在花括号中也可以。
之所以上面问题的解决方案可有:
1、用synchronized(this){}锁定当前对象
public void add(){
synchronized(this){
num++;
System.out.println("这是第 "+num+"次调用该方法");
}
}
2、用synchronized关键字修饰add方法使在add方法内锁定当前对象
public synchronized void add(){
num++;
System.out.println("这是第 "+num+"次调用该方法");
}
注:当一个线程类中有同步方法和非同步方法时,要仔细考虑可以访问关注对象的所有方法是否加锁。对于同步方法,只能有一个线程独占执行完成后释放。而非同步方法,可以由多个线程交叉访问。
对于一个对象,我们对对象"写"的方法需要设置为同步方法,这是因为多个同步方法都要锁定对象,所以,只有一个线程在一段时间内"写"该对象。"读"方法可以不用设置为同步(效率高)。
分享到:
相关推荐
Java线程讲解Java线程讲解Java线程讲解Java线程讲解Java线程讲解Java线程讲解Java线程讲解Java线程讲解Java线程讲解Java线程讲解
电子书相关:包含4个有关JAVA线程的电子书(几乎涵盖全部有关线程的书籍) OReilly.Java.Threads.3rd.Edition.Sep.2004.eBook-DDU Java Thread Programming (Sams) java线程第二版中英文 java线程第二版中英文 ...
Java线程Java线程Java线程Java线程Java线程Java线程Java线程Java线程Java线程Java线程Java线程Java线程Java线程Java线程Java线程
Java线程Java线程Java线程Java线程Java线程Java线程
Java线程:概念与原理 Java线程:创建与启动 Java线程:线程栈模型与线程的变量 Java线程:线程状态的转换 Java线程:线程的同步与锁 Java线程:线程的交互 Java线程:线程的调度-休眠 Java线程:线程的调度-优先级 ...
Java线程:线程的调度-终止线程 25 Java线程:线程的调度-守护线程 28 Java线程:线程组 30 Java线程:线程的同步 33 一、 同步方法 35 二、 同步块 36 三、 volatile关键字 38 四、 使用synchronized关键字要注意...
java 线程java 线程java 线程java 线程java 线程java 线程java 线程java 线程java 线程
Java 线程系列博文总结word化,编目如下,欢迎互相学习交流: Java线程:概念与原理 Java线程:创建与启动 Java线程:线程栈模型与线程的变量 Java线程:线程状态的转换 Java线程:线程的同步与锁 Java线程:...
Java线程模块Java线程之秒表新手学习Java线程模块时,利用Java中设置线程的暂停间隔,做的简易秒表
java线程 线程 教程 java线程教程 java线程学习资料 本教程有什么内容? 本教程研究了线程的基础知识— 线程是什么、线程为什么有用以及怎么开始编写使用线程的简单 程序。 我们还将研究更复杂的、使用线程的应用...
java 线程Dump 分析工具: Java的TDA线程转储分析器是一个用于分析Sun Java VM生成的线程转储和堆信息的小型Swing GUI(目前用1.4测试)。它从提供的日志文件中解析线程转储和类直方图。它提供关于发现的线程转储的...
java线程同步java线程同步java线程同步
java中 使用interrput 如何终止一个线程
java线程.pdf java 学习java
Java的线程和Java AppletJava的线程和Java AppletJava的线程和Java AppletJava的线程和Java AppletJava的线程和Java Applet
java 线程 新手java 线程 新手java 线程 新手java 线程 新手
分析java线程日志的工具,使用jstack把java线程日志dump下来,然后上传到该工具,就可以查看线程阻塞情况等信息。
Java线程如何终止.pdf
Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式...