学习记录一下:syncronized关键字的使用
public class TestJoin {
public static void main(String[] args) {
System.out.println(String.format("主线程%s 开始运行...", Thread.currentThread().getName()));
Thread threadA = new Thread(new ThreadA());
threadA.start();
try {
// 主线程 wait(0) 释放 thread 对象锁,主线程进入 waiting 状态
threadA.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(String.format("主线程%s 运行结束...", Thread.currentThread().getName()));
}
/**
* 创建一个内部类来进行操作
*/
private static class ThreadA implements Runnable{
@Override
public void run() {
System.out.println(String.format("子线程%s 开始运行...", Thread.currentThread().getName()));
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(String.format("子线程%s 准备结束运行...", Thread.currentThread().getName()));
}
}
}
测试二:
public class TestNotify {
public static void main(String[] args) {
new Thread(new ThreadA()).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(new ThreadB()).start();
}
private static final Object lock = new Object();
private static class ThreadA implements Runnable{
@Override
public void run() {
synchronized (lock){
System.out.println("Thread-A 进入状态 running...");
try {
System.out.println("Thread-A 进入状态 waiting...");
lock.wait();
System.out.println("Thread-A 进入状态 running...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Thread-A 执行完毕, 进入状态 terminated...");
}
}
private static class ThreadB implements Runnable{
@Override
public void run() {
synchronized (lock){
System.out.println("Thread-B 进入状态 running...");
try {
System.out.println("Thread-B 进入状态 time_waiting...");
Thread.sleep(3000);
System.out.println("Thread-B 进入状态 running...");
lock.notify();
System.out.println("Thread-B 进入状态 time_waiting...");
Thread.sleep(5000);
System.out.println("Thread-B 进入状态 running...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Thread-B 执行完毕, 进入状态 terminated...");
}
}
}
因为锁对象是同一个,那么关联的是同一个对象头,会在wait_set中进行等待,只有一个资源能够进入到onDeck中来,然后等待同步块中的线程来运行代码的时候,能够遇到wait或者是nofity来进行激活。
需要注意的是notify只是会通知,但是不会将锁释放掉。还是要等到当前代码块中的方法执行完成之后才会有对应的操作执行。
wait方法只是会释放掉当前的锁对象,然后让其他排队的线程来进行抢锁,可重入锁、但是是非公平的。
其实写个小的DEMO来验证一下即可:
public class WaitNofityDemo1 {
private static volatile int i = 0;
private static final Object obj = new Object();
public static class One implements Runnable {
@Override
public void run() {
// 这么来进行操作,那么会占满CPU的
synchronized (obj) {
while (!Thread.currentThread().isInterrupted()) {
if (i % 3 == 0) {
System.out.println("当前的i的值是:" + i);
i++;
obj.notifyAll();
}
try {
Thread.sleep(2000);
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public static class Two implements Runnable {
@Override
public void run() {
// 这么来进行操作,那么会占满CPU的
synchronized (obj) {
while (!Thread.currentThread().isInterrupted()) {
if (i % 3 == 2) {
System.out.println("当前的i的值是:" + i);
i++;
obj.notifyAll();
}
try {
Thread.sleep(2000);
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public static class Three implements Runnable {
@Override
public void run() {
// 这么来进行操作,那么会占满CPU的
synchronized (obj) {
while (!Thread.currentThread().isInterrupted()) {
if (i % 3 == 1) {
System.out.println("当前的i的值是:" + i);
i++;
obj.notifyAll();
}
try {
Thread.sleep(2000);
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args) {
Thread thread1 = new Thread(new One());
Thread thread2 = new Thread(new Two());
Thread thread3 = new Thread(new Three());
thread1.start();
thread2.start();
thread3.start();
}
}
其中,对于volatile关键字修饰的,无法保证其原子性,但是使用syncronized关键字可以来进行实现。所以加不加都可以。
notify和notifyAll的区别就在于随机唤醒一个和唤醒全部,让其来进行抢锁
public class WaitNotifyDemo {
private static final Object OBJECT = new Object();
private static int i = 0;
public static class RunnableA implements Runnable {
@Override
public void run() {
// 利用这个来进行操作
while (!Thread.currentThread().isInterrupted()) {
synchronized (OBJECT) {
if (i % 2 == 0) {
System.out.println("11111111111111111111111111");
i++;
OBJECT.notifyAll();
}
try {
Thread.sleep(1000);
OBJECT.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public static class RunnableB implements Runnable {
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
synchronized (OBJECT) {
if (i % 2 == 1) {
System.out.println("2222222222222222222222222");
i++;
OBJECT.notifyAll();
}
try {
Thread.sleep(1000);
OBJECT.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args) {
Thread thread1 = new Thread(new RunnableA());
Thread thread2 = new Thread(new RunnableB());
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
查看控制台输出即可。