[1] 线程、进程和程序
·线程和进程的区别
每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销。
线程可以看成是轻量级的进程,属于同一进程的线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换的开销小。
线程和进程最根本的区别在于:进程是资源分配的单位,线程是调度和执行的单位。
多进程: 在操作系统中能同时运行多个任务(程序)。
多线程: 在同一应用程序中有多个顺序流同时执行。
线程是进程的一部分,所以线程有的时候被称为轻量级进程。
一个没有线程的进程是可以被看作单线程的,如果一个进程内拥有多个线程,进程的执行过程不是一条线(线程)的,而是多条线(线程)共同完成的。
系统在运行的时候会为每个进程分配不同的内存区域,但是不会为线程分配内存(线程所使用的资源是它所属的进程的资源),线程组只能共享资源。那就是说,除了CPU之外(线程在运行的时候要占用CPU资源),计算机内部的软硬件资源的分配与线程无关,线程只能共享它所属进程的资源。与线程无关,线程只能共享它所属进程的资源。 节点流处于IO操作的第一线,所有操作必须通过它们进行;处理流可以对节点流进行包装,提高性能或提高程序的灵活性。
·进程与程序的区别
程序是一组指令的集合,它是静态的实体,没有执行的含义。而进程是一个动态的实体,有自己的生命周期。一般说来,一个进程肯定与一个程序相对应,并且只有一个,但是一个程序可以有多个进程,或者一个进程都没有。除此之外,进程还有并发性和交往性。简单地说,进程是程序的一部分,程序运行的时候会产生进程。
[2] 通过继承Thread类实现多线程
继承Thread类实现多线程的步骤:
第一步在Java中负责实现线程功能的类是java.lang.Thread 类。
第二步可以通过创建 Thread的实例来创建新的线程。
第三步每个线程都是通过某个特定的Thread对象所对应的方法run( )来完成其操作的,方法run( )称为线程体。
第四步通过调用Thread类的start()方法来启动一个线程。
public class TestThread extends Thread {//自定义类继承Thread类
//run()方法里是线程体
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(this.getName() + ":" + i);//getName()方法是返回线程名称
}
}
public static void main(String[] args) {
TestThread thread1 = new TestThread();//创建线程对象
thread1.start();//启动线程
TestThread thread2 = new TestThread();
thread2.start();
}
}
[3] 通过Runnable接口实现多线程
public class TestThread2 implements Runnable {//自定义类实现Runnable接口;
//run()方法里是线程体;
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
public static void main(String[] args) {
//创建线程对象,把实现了Runnable接口的对象作为参数传入;
Thread thread1 = new Thread(new TestThread2());
thread1.start();//启动线程;
Thread thread2 = new Thread(new TestThread2());
thread2.start();
}
}
[4] 终止线程的典型方式
提供一个boolean型的终止变量,当这个变量置为false,则终止线程的运行。
public class TestThreadCiycle implements Runnable {
String name;
boolean live = true;// 标记变量,表示线程是否可中止;
public TestThreadCiycle(String name) {
super();
this.name = name;
}
public void run() {
int i = 0;
//当live的值是true时,继续线程体;false则结束循环,继而终止线程体;
while (live) {
System.out.println(name + (i++));
}
}
public void terminate() {
live = false;
}
public static void main(String[] args) {
TestThreadCiycle ttc = new TestThreadCiycle("线程A:");
Thread t1 = new Thread(ttc);// 新生状态
t1.start();// 就绪状态
for (int i = 0; i < 100; i++) {
System.out.println("主线程" + i);
}
ttc.terminate();
System.out.println("ttc stop!");
}
}
[5] 暂停线程执行sleep/yield
Sleep:
public class TestThreadState {
public static void main(String[] args) {
StateThread thread1 = new StateThread();
thread1.start();
StateThread thread2 = new StateThread();
thread2.start();
}
}
//使用继承方式实现多线程
class StateThread extends Thread {
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(this.getName() + ":" + i);
try {
Thread.sleep(2000);//调用线程的sleep()方法;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Yield:
public class TestThreadState {
public static void main(String[] args) {
StateThread thread1 = new StateThread();
thread1.start();
StateThread thread2 = new StateThread();
thread2.start();
}
}
//使用继承方式实现多线程
class StateThread extends Thread {
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(this.getName() + ":" + i);
Thread.yield();//调用线程的yield()方法;
}
}
}
[6] 线程的联合join()
线程A在运行期间,可以调用线程B的join()方法,让线程B和线程A联合。这样,线程A就必须等待线程B执行完毕后,才能继续执行。
public class TestThreadState {
public static void main(String[] args) {
System.out.println("爸爸和儿子买烟故事");
Thread father = new Thread(new FatherThread());
father.start();
}
}
class FatherThread implements Runnable {
public void run() {
System.out.println("爸爸想抽烟,发现烟抽完了");
System.out.println("爸爸让儿子去买包红塔山");
Thread son = new Thread(new SonThread());
son.start();
System.out.println("爸爸等儿子买烟回来");
try {
son.join();
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("爸爸出门去找儿子跑哪去了");
// 结束JVM。如果是0则表示正常结束;如果是非0则表示非正常结束
System.exit(1);
}
System.out.println("爸爸高兴的接过烟开始抽,并把零钱给了儿子");
}
}
class SonThread implements Runnable {
public void run() {
System.out.println("儿子出门去买烟");
System.out.println("儿子买烟需要10分钟");
try {
for (int i = 1; i <= 10; i++) {
System.out.println("第" + i + "分钟");
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("儿子买烟回来了");
}
}
[7] 获取线程基本信息的方法
public class TestThread {
public static void main(String[] argc) throws Exception {
Runnable r = new MyThread();
Thread t = new Thread(r, "Name test");//定义线程对象,并传入参数;
t.start();//启动线程;
System.out.println("name is: " + t.getName());//输出线程名称;
Thread.currentThread().sleep(5000);//线程暂停5分钟;
System.out.println(t.isAlive());//判断线程还在运行吗?
System.out.println("over!");
}
}
class MyThread implements Runnable {
//线程体;
public void run() {
for (int i = 0; i < 10; i++)
System.out.println(i);
}
}