从一道题开始
java三个线程分别打印ABC,按“ABC”顺序打印十遍,嗯嗯
分析
多线程问题,查了不少资料写出了代码。
1.java线程状态
New (新建状态):新创建了一个线程对象
Runnable (就绪状态):线程对象创建后,调用了该对象的start()方法之后,该状态的线程就位于可运行线程池中,变得可运行,等待获取CPU的使用权
Running (运行状态):就绪状态的线程获取了CPU,开始执行程序代码
Blocked (阻塞状态):线程因为某种原因放弃了CPU使用权,暂时停止运行状态,知道再次进入Runnable状态,才有机会再次Running。
阻塞情况分为三种:
①等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待线程池里(wait会释放持有的锁)
②同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用、或者I/O处理完毕时,线程重新转入就绪状态。(需要注意,sleep不会释放持有的锁)
③其他阻塞:运行的线程执行sleep()或join()方法时,JVM会把线程设置为阻塞
Dead (死亡状态):线程执行完毕或者由于异常退出了run方法,该线程结束了生命周期
如图

2.线程方法
①join方法:
join方法使当前线程阻塞,等待调用join方法的线程执行,可以使得线程之间的并行执行变为串行执行
举个例子:
main(){
ThreadJoinTest t1 = new ThreadJoinTest("小明");
ThreadJoinTest t2 = new ThreadJoinTest("小东");
t1.start();
t1.join();
t2.start();
}
程序在main线程中调用t1线程的join方法,则main线程放弃cpu控制权,并返回t1线程继续执行直到线程t1执行完毕。所以结果是t1线程执行完后,才到主线程执行,相当于在main线程中同步t1线程,t1执行完了,main线程才有执行的机会
②sleep方法
sleep方法暂停当前线程,把CPU片段让出给其他线程,减缓当前线程的执行。休眠时间结束,线程进入就绪状态
③yield方法
yield方法使线程进入就绪状态,所以执行yield()的线程有可能在进入到就绪状态后马上又被执行。
④wait方法和notify方法
wait方法使当前线程进入等待状态,同时,wait()也会让当前线程释放它所持有的锁。直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,当前线程就被唤醒(进入“就绪状态”)
notify方法是唤醒单个进程,notifyAll是唤醒所有进程
3.锁
以多窗口售票系统为例,剩余票的数量是固定的,所有窗口共享这个数值。锁的存在,就保证了在同一时间只有一个线程访问方法或变量,保证了“同步”。
题解
思路:创建三个线程,每个线程持有两把锁,是自身对象锁和前一个线程的对象所。
MyThread.class
public class MyThread implements Runnable{
private String name;
private Object pre;
private Object self;
public MyThread(String name,Object pre,Object self) {
this.name = name;
this.pre = pre;
this.self = self;
}
@Override
public void run() {
for (int i=0;i<11;i++) {
synchronized (pre) {
synchronized (self) {
System.out.println(name);
self.notify();
}
try{
//最后一次,防止死锁
if (i<10) pre.wait();
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Main
import static java.lang.Thread.sleep;
public class Main {
public static void main(String[] args) throws InterruptedException {
Object a = new Object();
Object b = new Object();
Object c = new Object();
Thread A = new Thread(new MyThread("A",c,a));
Thread B = new Thread(new MyThread("B",a,b));
Thread C = new Thread(new MyThread("C",b,c));
A.start();
//保证A B C执行顺序
sleep(10);
B.start();
sleep(10);
C.start();
}
}
网友评论