join---->Thread类
设计一个模型
1.有两个线程 One Two two加入到one里面
2.设计模型时候 two线程在one的run里面创建 保证两个有先后顺序
3.two.join(); 无参数==0 有参数==2000
one 启动
two 启动
three 启动
two就join啦
2000之后 one想要将two从自己的线程内剔除
two对象不在自己的手里 对象被three线程锁定啦 10000
one只能等待 threee将two对象释放后 才能踢掉
synchronized锁 非常的厉害
一旦对象被锁定 不释放的情况下 其他的对象都需要等待
有可能会产生一个死锁的效果
死锁的效果
模拟一个模型 演示死锁
如何解决死锁效果
经典的哲学家就餐问题
解决死锁的问题
1.礼让---->产生时间差
2.不要产生对象公用的问题
计时器/定时器----->线程应用
java.util包
Timer类
无参数构造方法 创建对象
timer.schedule();
package com.uncle.testthread.testjoin;
public class TestMain {
public static void main(String[] args){
ThreadOne one = new ThreadOne();
one.start();
}
}
package com.uncle.testthread.testjoin;
public class ThreadOne extends Thread {
public void run(){
System.out.println("thread-one start");
ThreadTwo two = new ThreadTwo();
two.start();
try {
two.join(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread-one end");
}
}
package com.uncle.testthread.testjoin;
public class ThreadTwo extends Thread {
public void run(){
System.out.println("thread-two start");
ThreadThree three = new ThreadThree(this);
three.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread-two end");
}
}
package com.uncle.testthread.testjoin;
public class ThreadThree extends Thread{
private ThreadTwo two;
public ThreadThree(ThreadTwo two){
this.two=two;
}
public void run(){
System.out.println("thread-three start");
synchronized(two){
System.out.println("two is locked");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("two is free");
}
System.out.println("thread-three end");
}
}
package com.uncle.testthread.testtimer;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class TestTimer {
private int count = 1;
private ArrayList<String> userBox = new ArrayList<String>();
{
userBox.add("a");userBox.add("b");userBox.add("d");userBox.add("d");
}
public void test() throws ParseException {
System.out.println("预备备 开始~");
Timer timer = new Timer();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date firstTime = sdf.parse("2019-01-31 11:53:20");
timer.schedule(new TimerTask(){
public void run() {
System.out.println("第"+count+++"次执行");
for(int i=0;i<userBox.size();i++){
System.out.println("给"+userBox.get(i)+"发送了一条消息:[步尔斯特很帅!!!]");
}
System.out.println("做了点坏事儿 真开心~~~");
}
},firstTime,3000);
}
public static void main(String[] args){
try {
TestTimer tt = new TestTimer();
tt.test();
} catch (ParseException e) {
e.printStackTrace();
}
}
}
package com.uncle.testthread.philosopher;
public class TestMain {
public static void main(String[] args){
Chopstick c1 = new Chopstick(1);
Chopstick c2 = new Chopstick(2);
Chopstick c3 = new Chopstick(3);
Chopstick c4 = new Chopstick(4);
Philosopher p1 = new Philosopher("哲学家a",c2,c1,0);
Philosopher p2 = new Philosopher("哲学家b",c3,c2,3000);
Philosopher p3 = new Philosopher("哲学家c",c4,c3,0);
Philosopher p4 = new Philosopher("哲学家d",c1,c4,3000);
p1.start();
p2.start();
p3.start();
p4.start();
}
}
package com.uncle.testthread.philosopher;
public class Chopstick {
private int num;
public Chopstick(int num){
this.num=num;
}
public int getNum(){
return this.num;
}
}
package com.uncle.testthread.philosopher;
public class Philosopher extends Thread{
private String pname;
private Chopstick left;
private Chopstick right;
private long time;
public Philosopher(String pname,Chopstick left,Chopstick right,long time){
this.pname = pname;
this.left = left;
this.right = right;
this.time = time;
}
public void run(){
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (left) {
System.out.println(this.pname+"拿起了左手边的"+this.left.getNum()+"筷子");
synchronized (right){
System.out.println(this.pname+"拿起了右手边的"+this.right.getNum()+"筷子");
System.out.println(this.pname+"开始狼吞虎咽的吃起来啦");
}
}
}
}
- join方法有关示意图
- 科学家就餐图