注意点:
线程其实是被轮流执行的,Java虚拟机快速地把控制从一个线程切换到另一个线程
Java应用程序总是从主类的main方法开始执行,(static),当JVM加载并发现main方法后
举例子:两个以上的无限循环
线程的状态与生命周期:
Java语言使用Thread类及其子类的对象来表示线程,新建的线程在它的一个完整的生命周期中通长要经历4个状态
①新建 使用Thread类或其子类创建新的对象,此时已经拥有相应的内存空间与其他资源
②运行 线程创建了之后就具备了运行的条件,但JVM中还没有此线程,必须调用
**start()**方法通知JVM。如果线程是Thread的子类创建的,该类中的run()方法就立刻执行,该方法规定了该线程的具体使命。因此程序必须在子类中重写父类的run()方法。
在线程没有结束run()之前,不要在调用start()方法,否则将发生IllegalThreadStateException异常。
③中断 有四种原因
First JVM将CPU(CPU具体是什么)切换给了其他线程
Second 线程使用CPU资源期间,执行了 sleep(int millsecond) 方法,使当前线程进入休眠状态。
Third 线程使用CPU资源期间,执行了wait()方法,使得当前线程进入等待状态。等待状态的线程不会主动去排队,必须由其他线程调用notify()方法通知它,使得它重新进到线程队列排队等待资源。
Forth 线程使用CPU期间,发生阻塞,如读/写引起的阻塞。进入阻塞状态的线程不能进入排队队列,阻塞消除时才能重新等待CPU资源。
④死亡
First 执行完了全部run()语句
Second run()方法被强制结束
线程调度与优先级
setPriority(int grade)
在实际编程时,不提倡使用线程的优先级来保证算法的正确执行,要编写正确、跨平台的多线程代码,必须假设线程在任何时刻都有可能被剥夺CPU资源的使用权。
Thread类与线程的创建
使用runnable接口的好处:
不同线程可以使用同一目标对象
//构造方法 Thread(Runnable target)
public class example_1{
public static void main(String []args) {
House house1 = new House();
house1.setWater(10);
Thread dog,cat;
dog = new Thread(house1);
cat = new Thread(house1);
dog.setName("小狗");
cat.setName("小猫");
dog.start();
cat.start();
}
}
class House implements Runnable {
int waterAmout;
public void setWater(int w) {
waterAmout = w;
}
public void run() {
while (true) {
String name = Thread.currentThread().getName();//现在的进程
if (name.equals("小狗")) {
System.out.println(name + "喝水");
waterAmout = waterAmout - 2;
} else if (name.equals("小猫")) {
System.out.println(name + "喝水");
waterAmout = waterAmout - 3;
}
System.out.println("还剩" + waterAmout);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
if (waterAmout <= 0) {
return;
}
}
}
}
目标对象与线程间的关系
从对象和对象之间的关系角度来看,目标对象和线程的关系有以下两种情景。
①目标对象和线程完全 解耦
String name = Thread.currentThread().getName();
创建的目标对象不包含堆线程对象的引用
②目标对象组合线程 (弱耦合)
Thread.curruentThread();
将线程作为自己的成员
//说实话不太懂
package example;
public class example_1{
public static void main(String []args) {
House house1 = new House();
house1.setWater(10);
house1.dog.start();
house1.cat.start();
}
}
class House implements Runnable {
int waterAmout;
Thread dog,cat;
House(){
dog = new Thread(this);
cat = new Thread(this);
}
public void setWater(int w) {
waterAmout = w;
}
public void run() {
while (true) {
Thread t = Thread.currentThread();
//String name = Thread.currentThread().getName();
if (t==dog) {
System.out.println("家狗喝水");
waterAmout = waterAmout - 2;
} else if (t==cat) {
System.out.println("家猫喝水");
waterAmout = waterAmout - 3;
}
System.out.println("还剩" + waterAmout);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
if (waterAmout <= 0) {
return;
}
}
}
}
关于run方法启用的次数:
可能随时终止,比如说waterAmount,systemout等处