----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
1 > 什么叫做进程? 什么叫做线程? 线程与进程的区别?
在多任务系统中,每个独立执行的程序称为进程,也就是正在进行的程序。我们现在使用的操作系统一般都是多任务的,即能够同时执行多个应用程序。实际情况是,操作系统负责对CPU等设备的资源进行分配和管理,虽然这些设备某一时刻只做一件事,但以非常小的时间间隔交替执行多个程序,就可以给人以同时执行多个程序的感觉。
一个进程中可以包含一个或多个线程,一个线程就是程序内部的一条执行线索。如果要一个程序中实现多段代码同时交替运行,就需产生多个线程,并指定每个线程上所要运行的程序代码段,这就是多线程。
进程是程序的一次动态执行过程,它经历了从代码加载,执行到执行完毕的一个完整过程,这个过程也是进程本身从产生,发展到最终消亡的过程.多进程操作系统能同时运行多个进程(程序),由于cpu具备分时机制,所以每个进程都能循环获得自己的cpu时间片.由于cpu执行速度非常快,使得所有的程序好像在”同时”运行一样.
线程是比进程更小的执行单位,线程是在进程的基础之上进行的进一步划分.所谓多线程是指一个进程在执行过程中可以产生多个线程,这些线程可以同时存在, 同时运行,形成多条执行线索,一个进程可能包含了多个同时执行的线程.
2 > 单线程与多线程的区别,前台线程与后台线程的区别。
单线程就是运行的顺序总是必须顺着程序的流程来走,遇到if-else语句就加以判断,遇到for,while等循环就会多绕几个圈,最后程序还是接着一定的程序走,且一次只能运行一个程序块。
多线程打破了这种传统的束缚,可以同时运行多个程序块,使程序运行的效率变得更高,也可克服传统程序语言所无法解决的问题.
在对某个线程对象在启动(调用start()方法)之前没有调用setDaemon(true)或setDaemon(false),这个线程就是前台线程.
在对某个线程对象在启动(调用start()方法)之前调用setDaemon(true)方法,这个线程就是后台线程.
对java程序来说,只要有一个前台线程在运行,这个进程就不会结束,如果一个进程中只有后台线程在运行,这个进程就会结束。
3 > 联合线程
联合线程就是用join()方法调用该线程对象的线程到其他线程中。
4 >怎样去激活线程?
有两种方式:
one :通过继承Thread类实现多线程。
缺点:Java程序只允许单一继承,即一个子类只能有一个父类,所以在java中如果一个类继承了某一个类,同时又想采用多线程技术的时,就不能用Thread类产生线程,因为java不允许多继承。同时用这种方式不能处理同一个资源。
tow :通过实现Runnable接口实现多线程。
用Runnable接口的优势:
(1):适合多个相同程序代码的线程去处理统一资源的情况,把虚拟cpu(线程) 同程序的代码,数据有效分离,较好的体现了面向对象的设计思想.
(2):可以避免由于Java的单继承特性带来的局限.开发中经常碰到这样一种情况,即:当要将已经继承了某一个类的子类放入多线程中,由于一个类不能同时有两个父类,所以不能用继承Thread类的方式,那么就只能采用实现Runnable接口的方式了.
(3):增强了程序的健壮性,代码能够被多个线程共享,代码与数据是独立的,当多个线程的执行代码来自同一个类的实例时,即称它们共享相同的代码.多个线程可以操作相同的数据,与它们的代码无关.当共享访问相同的对象时,即共享相同的数据.当线程被构造时,需要的代码和数据通过一个对象作为构造方法实参传递进去,这个对象就是一个实现了Runnable接口的类的实例.
5 > 多线程的同步—什么是线程安全?
如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。
或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。
线程安全问题都是由全局变量及静态变量引起的。
若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则就可能影响线程安全。
6 > 多线程的同步的两种方式
第一:使用同步代码块: synchronized(监视器对象){}
第二:使用同步函数: public synchronized void get(){}
代码块与函数直接的同步必须用同一个监视器对象,才能够达成两个线程的同步。 如果监视器对象不是同一个对象,则无法同步。
7 > 死锁问题
死锁是由于两个或多个线程都无法得到相应的监视器而造成相互等待,所以造成死锁的现象。
8 >线程之间的通信
wait:告诉当前线程放弃监视器并进入睡眠状态,直到其他线程进入同一监视器并调用notify为止。
notify:唤醒同一对象监视器中调用wait的第一个线程。用于类似饭馆有一个空位后通知所有等候就餐的顾客中的一位可以入座的情况。
notifyAll:唤醒同一对象监视器中调用wait的所有线程,具有最高优先级的线程首先被唤醒并执行。用于类型某个不定期的培训终于招生满额后,通知所有的学员都来上课的情况。
9 > 线程的生命控制
10 > 如何控制线程的生命
package thread;
//生产者
public class Producer implements Runnable {
Q q ;
public Producer(Q q){
this.q = q;
}
int i=0;
public void run(){
while(true){
if(i == 0){
q.put("zhangsan", "male");
}else{
q.put("lisi", "female");
}
i=(i+1)%2;
}
}
}
package thread;
//消费者
public class Consumer implements Runnable {
Q q;
public Consumer(Q q){
this.q = q;
}
public void run(){
while(true){
q.get();
}
}
}
package thread;
public class Q {
/**
* @param args
*/
private String name="unkown";
private String sex = "unkown";
boolean bFull = false;
public synchronized void put(String name,String sex){
if(bFull){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.name = name;
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.sex = sex;
bFull = true;
notify();
}
public synchronized void get(){
if(!bFull){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.print(name);
System.out.println(":"+sex);
bFull = false;
notify();
}
}
package thread;
public class ThreadCommunation {
public static void main(String[] args) {
ThreadTest t = new ThreadTest();
new Thread(t).start();
for (int i = 0; i < 100; i++) {
if(i == 50){
t.stopMe();
}
System.out.println("main is running:"+Thread.currentThread().getName());
}
}
----------------------- android培训、java培训、java学习型技术博客、期待与您交流! ----------------------
详情请查看: