我们先随意来整个没锁的果奔看看情况怎么样!
package baguwennonononononononononoooooo;
public class Run implements Runnable{
private int number = 1;
@Override
public void run() {
while (number < 100) {
System.out.println(Thread.currentThread().getName() + "正在打印" + number++);
}
}
public static void main(String[] args) {
Run run = new Run();
Thread r1 = new Thread(run);
Thread r2 = new Thread(run);
r1.setName("这是第一个线程");
r2.setName("这是第二个线程");
r1.start();
r2.start();
}
执行一下看看结果!
惊讶的发现第一行第二行打印出来的数就惊人的一致
所以这样时不行的哦
现在我们给它加一个synchronized锁试试看!
package baguwen;
public class Run implements Runnable{
private int number = 1;
@Override
public void run() {
while (number < 100) {
synchronized (this) {
System.out.println(Thread.currentThread().getName() + "正在打印" + number++);
}
}
}
public static void main(String[] args) {
Run run = new Run();
Thread r1 = new Thread(run);
Thread r2 = new Thread(run);
r1.setName("这是第一个线程");
r2.setName("这是第二个线程");
r1.start();
r2.start();
}
}
跑出来后运行结果是
你会发现第一个线程根本没有把锁释放掉, 第二个线程根本没法运行
所以我们再改改
用wait()方法让第一个线程等等第二个线程
调用wait方法会释放锁
package baguwen;
public class Run implements Runnable{
private int number = 1;
@Override
public void run() {
while (number < 100) {
synchronized (this) {
System.out.println(Thread.currentThread().getName() + "正在打印" + number++);
try {
wait();
}catch (Exception e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
Run run = new Run();
Thread r1 = new Thread(run);
Thread r2 = new Thread(run);
r1.setName("这是第一个线程");
r2.setName("这是第二个线程");
r1.start();
r2.start();
}
}
你会发现它们都只打印了一次, 并且没有接着运行(因为他们都在等待你(x
因为你没有唤醒它! 线程就不会接着往下去执行
那我们就调用notifyAll()来唤醒沉睡的多拉贡
package baguwen;
public class Run implements Runnable{
private int number = 1;
@Override
public void run() {
while (number <= 100) {
synchronized (this) {
notifyAll();
System.out.println(Thread.currentThread().getName() + "正在打印" + number++);
try {
wait();
}catch (Exception e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
Run run = new Run();
Thread r1 = new Thread(run);
Thread r2 = new Thread(run);
r1.setName("这是第一个线程");
r2.setName("这是第二个线程");
r1.start();
r2.start();
}
}
Okay!
如果想要慢慢打出来的话, 你可以让它睡一会!
在notifyAll后面增加一个
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
它就会一秒打印一个慢慢来打印!