信息共享
继承Thread的类通过static共享变量;
实现Runnable接口的类私有变量即可。
对于信息共享数据不一致的问题:
1.副本变量用volatile关键字修饰;保证不同线程共享变量操作的可见性。
2. 关键步骤加锁限制:
互斥:某一线程运行时候,其他线程不可运行,采用:synchronized修饰。
同步:各个线程按照一定的先后顺序执行。
多线程管理
其中关于线程间的阻塞/唤醒方法:
- sleep()
- wait(), notify(), notifyAll().
- join():等待另一个线程结束
- interrupt(), 向另一个程序发送中断信号,该程序收到中断信号后,会触发InterruptedException,可进行下一步。
例子1:
定义两个线程类,均继承Thread类。
TestThread11:采用interrupt()方法进行中断程序;
TestThread22:采用标志flag来停止该线程。且flag采用volatile修饰,是安全的多个线程共享变量。
package multiThread;
public class InterruptedThread {
public static void main(String[] args) throws InterruptedException {
TestThread11 t1 = new TestThread11();
TestThread22 t2 = new TestThread22();
t1.start();
t2.start();
Thread.sleep(2000);
t1.interrupt();
t2.flag = false;
System.out.println("main Thread is exiting!");
}
}
class TestThread11 extends Thread{
public void run() {
while(!interrupted()) {
System.out.println("Thread1 is running!");
try {
Thread.sleep(1000);
}catch(InterruptedException e) {
e.printStackTrace();
break;
}
}
System.out.println("Thread1 is exiting!");
}
}
class TestThread22 extends Thread{
public volatile boolean flag = true;
public void run() {
while(flag) {
System.out.println("Thread2 is running!");
try {
Thread.sleep(1000);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Thread2 is exiting!");
}
}
例2:
为了实现线程之间的同步,采用synchronized修饰关键字段,二者分别要依次获取变量r1,r2才可以执行。就如同哲学家吃面的问题。
package multiThread;
import java.util.concurrent.TimeUnit;
public class TestDemo5 {
public static Integer r1 = 1;
public static Integer r2 = 2;
public static void main(String[] args) {
Demo1 t1 = new Demo1();
Demo2 t2 = new Demo2();
t1.start();
t2.start();
}
}
class Demo1 extends Thread{
public void run() {
synchronized(TestDemo5.r1){
try {
TimeUnit.SECONDS.sleep(2);
}catch(InterruptedException e){
e.printStackTrace();
}
synchronized(TestDemo5.r2) {
System.out.println("Thread1 is exiting!");
}
}
}
}
class Demo2 extends Thread{
public void run() {
synchronized(TestDemo5.r1) {
try {
TimeUnit.SECONDS.sleep(2);
}catch(InterruptedException e) {
e.printStackTrace();
}
synchronized(TestDemo5.r2) {
System.out.println("Thread2 is exiting!");
}
}
}
}