- 多线程编程的目的:最大限度地利用CPU资源”,当某一线程的处理不需要占用CPU而只和I/O,OEMBIOS等资源打交道时,让需要占用CPU资源的其它线程有机会获得CPU资源。从根本上说,这就是多线程编程的最终目的。
- 线程对象和线程的区别:【线程对象】是可以产生线程的对象。比如在Java平台中Thread对象,Runnable对象。【线程】是指正在执行的一个指点令序列。在java平台上是指从一个线程对象的start()开始,运行run方法体中的那一段相对独立的过程。
- 单线程:JVM最先会产生一个主线程,由它来运行指定程序的入口点。在这个程序中,就是主线程从main方法开始运行。当main方法结束后,主线程运行完成。JVM进程也随之退出。
- 线程的并发和并行:【并发】在单CPU系统中要通过不断切换需要运行的线程让其运行的方式。【并行】在多CPU系统中,可以让两个以上的线程同时运行。
5. 开始一个线程的两种的方式:
【直接调用Thread实例的start()方法】
class MyThread extends Thread{
public int x = 0;
public void run(){
for(int i=0;i<100;i++){
try{
Thread.sleep(10);
}catch(Exception e){}
System.out.println(x++);
}
}
}
》》由于单CPU的原因,一般会先打印101,然后打印0到99
public class Test {
public static void main(String[] args) throws Exception{
MyThread mt = new MyThread();
mt.start();
System.out.println(101);
}
}
》》不过我们可以控制线程让它按我们的意思来运行:
public class Test {
public static void main(String[] args) throws Exception{
MyThread mt = new MyThread();
mt.start();
mt.join();
System.out.println(101);
}
}
》》在线程对象a上调用join()方法,就是让当前正在执行的线程等待线程对象a对应的线程运行完成后才继续运行
》》mt实例对应的线程在运行完成后,主线程才打印101。因为我们让当前线程(这里是主线程)等待mt线程的运行结束
重要例子:
public class Test {
public static void main(String[] args) throws Exception{
MyThread mt = new MyThread();
mt.start();
mt.join();
//当线程对象mt运行完成后,我们让主线程休息一下
Thread.sleep(3000);
//再次在这个线程对象上启动线程
mt.start();
}
}
结果:Exception in thread "main" java.lang.IllegalThreadStateException
原因:一个Thread的实例一旦调用start()方法,这个实例的started标记就标记为true,事实中不管这个线程后来有没有执行到底,只要调用了一次start()就再也没有机会运行了
[通过Thread实例的start(),一个Thread的实例只能产生一个线程]
一个实例上产生多个线程(也就是我们常说的线程池),引出Runnable接口
【将Runable实例传给一个Thread实例然后调用它的start()方法】
两者对比:
import java.io.*;
import java.lang.Thread;
//第一种方式
class MyThread extends Thread{
public int x = 0;
public void run(){
System.out.println(++x);
}
}
//第二种方式
class R implements Runnable{
private int x = 0;
public void run(){
System.out.println(++x);
}
}
public class Test {
public static void main(String[] args) throws Exception{
for(int i=0;i<10;i++){
Thread t = new MyThread();
t.start();
}
//10个线程对象产生的10个线程运行时打印了10次1
Thread.sleep(10000);//让上面的线程运行完成
R r = new R();
for(int i=0;i<10;i++){
Thread t = new Thread(r);
t.start();
}
//10个线程对象产生的10个线程运行时打印了1到10。我们把下面的10个线程称为同一实例(Runnable实例)的多个线程
}
}