使用synchronize和RenentrantLock循环打印指定量数字或字母ABC

Synchronized和ReentrantLock优缺点

synchronize关键字,优点:
1.不需要手动解锁,不会造成死锁
2.JDK1.8之后对其进行升级优化,性能和ReentrantLock相当
3.可重入锁
缺点:
1.不能终止锁
2.非公平锁
3.解锁后唤起任意阻塞线程

ReentrantLock类,优点:
1.可以通过设置超时时间终止锁
2.可以是公平锁,也可以是非公平锁
3.可重入锁
4.可根据condition唤醒符合条件的线程
缺点:
1.需要手动解锁,可能造成死锁

指定线程数量循环打印数字

使用synchronized关键字实现

public class LoopPrint {

    public static volatile Integer index = 0;
    public static final int THREAD_COUNT = 3;
    public static final int MAX_COUNT = 15;
    public static final Object OBJ = new Object();

    public static ReentrantLock lock = new ReentrantLock();

    public static void main(String[] args) {
        for (int i = 0; i < THREAD_COUNT; i++) {
            new Thread(new PrintThread(i), i + "").start();
        }
    }
}

class PrintThread implements Runnable {
    private int index;

    public PrintThread(int index) {
        this.index = index;
    }

    @Override
    public void run() {
        while (true) {
            synchronized (LoopPrint.OBJ) {
                while (LoopPrint.index % LoopPrint.THREAD_COUNT != index) {
                    if (LoopPrint.index >= LoopPrint.MAX_COUNT) {
                        break;
                    }
                    try {
                        LoopPrint.OBJ.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if (LoopPrint.index >= LoopPrint.MAX_COUNT) {
                    break;
                }
                System.out.println(Thread.currentThread().getName() + "线程执行: " + LoopPrint.index);
                LoopPrint.index++;
                LoopPrint.OBJ.notifyAll();
            }
        }
    }
}

0线程执行: 0
1线程执行: 1
2线程执行: 2
0线程执行: 3
1线程执行: 4
2线程执行: 5
0线程执行: 6
1线程执行: 7
2线程执行: 8
0线程执行: 9
1线程执行: 10
2线程执行: 11
0线程执行: 12
1线程执行: 13
2线程执行: 14

使用ReentrantLock实现

public class LoopPrint {

    public static volatile Integer index = 0;
    public static final int THREAD_COUNT = 3;
    public static final int MAX_COUNT = 15;
    public static final Object OBJ = new Object();

    public static ReentrantLock lock = new ReentrantLock();

    public static void main(String[] args) {
        for (int i = 0; i < THREAD_COUNT; i++) {
            new Thread(new PrintLockThread(i), i + "").start();
        }
    }

}

class PrintLockThread implements Runnable {
    private int index;

    public PrintLockThread(int index) {
        this.index = index;
    }

    @Override
    public void run() {
        while (true) {
            try {
                LoopPrint.lock.lock();
                if (LoopPrint.index >= LoopPrint.MAX_COUNT) {
                    break;
                }
                if (LoopPrint.index % LoopPrint.THREAD_COUNT == index) {
                    System.out.println(Thread.currentThread().getName() + "线程执行: " + LoopPrint.index);
                    LoopPrint.index++;
                }
            } finally {
                LoopPrint.lock.unlock();
            }
        }
    }
}

0线程执行: 0
1线程执行: 1
2线程执行: 2
0线程执行: 3
1线程执行: 4
2线程执行: 5
0线程执行: 6
1线程执行: 7
2线程执行: 8
0线程执行: 9
1线程执行: 10
2线程执行: 11
0线程执行: 12
1线程执行: 13
2线程执行: 14

3个线程循环打印字母ABC

使用synchronized关键字实现

public class ThreadTest {
    private static int number = 1;

    public static void main(String[] args) {
        new Thread(() -> {
            while (true) {
                synchronized (ThreadTest.class) {
                    while (number != 1) {
                        try {
                            ThreadTest.class.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    number = 2;
                    System.out.println("A");
                    ThreadTest.class.notifyAll();
                }
            }
        }).start();

        new Thread(() -> {
            while (true) {
                synchronized (ThreadTest.class) {
                    while (number != 2) {
                        try {
                            ThreadTest.class.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    number = 3;
                    System.out.println("B");
                    ThreadTest.class.notifyAll();
                }
            }
        }).start();

        new Thread(() -> {
            while (true) {
                synchronized (ThreadTest.class) {
                    while (number != 3) {
                        try {
                            ThreadTest.class.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    number = 1;
                    System.out.println("C");
                    ThreadTest.class.notifyAll();
                }
            }
        }).start();
    }
}

使用ReentrantLock及Condition实现, 精准唤醒线程

public class ReentrantLockTest {

    private static Lock lock = new ReentrantLock();
    private static Condition cA = lock.newCondition();
    private static Condition cB = lock.newCondition();
    private static Condition cC = lock.newCondition();
    private static int number = 1;

    public static void main(String[] args) {
        new Thread(() -> {
            while (true) {
                lock.lock();
                try {
                    while (number != 1) {
                        cA.await();
                    }
                    System.out.println("A");
                    number = 2;
                    cB.signalAll();
                } catch (Exception e) {
                } finally {
                    lock.unlock();
                }
            }
        }).start();

        new Thread(() -> {
            while (true) {
                lock.lock();
                try {
                    while (number != 2) {
                        cB.await();
                    }
                    System.out.println("B");
                    number = 3;
                    cC.signalAll();
                } catch (Exception e) {
                } finally {
                    lock.unlock();
                }
            }
        }).start();

        new Thread(() -> {
            while (true) {
                lock.lock();
                try {
                    while (number != 3) {
                        cC.await();
                    }
                    System.out.println("C");
                    number = 1;
                    cA.signalAll();
                } catch (Exception e) {
                } finally {
                    lock.unlock();
                }
            }
        }).start();
    }
}

运行结果

A
B
C
A
B
C
A
B
C
A
B
C
A
B
C
...
### 回答1: reentrantlocksynchronize都是Java中用于实现线程同步的机制。 synchronize是Java中最基本的同步机制,它可以用于同步方法和同步代码块。synchronize实现是基于Java对象的内置锁(monitor)来实现的,每个Java对象都有一个内置锁,当一个线程访问一个同步方法或同步代码块时,它会自动获取该对象的内置锁,其他线程则必须等待该线程释放锁后才能访问该方法或代码块。 reentrantlock是Java中的高级同步机制,它提供了更多的功能和灵活性。reentrantlock可以用于同步代码块,但不能用于同步方法。reentrantlock实现是基于Java的Lock接口来实现的,它提供了更多的方法来控制锁的获取和释放,例如可以设置锁的公平性、可以中断等待锁的线程、可以获取锁的持有者等。 总的来说,synchronize是Java中最基本的同步机制,使用起来简单方便,但功能相对较少;reentrantlock是Java中的高级同步机制,功能更加强大,但使用起来相对复杂一些。在实际开发中,应根据具体情况选择合适的同步机制。 ### 回答2: ReentrantLocksynchronize是Java中用于实现线程同步的两种机制。 ReentrantLock是Java.util.concurrent包中提供的一种可重入的互斥锁。相比synchronize,ReentrantLock提供了更灵活的锁定机制。通过调用lock()方法获取锁,调用unlock()方法释放锁。与synchronize相比,ReentrantLock具有锁的可重入性,即同一个线程可以多次获取同一个锁,而不会被阻塞。此外,ReentrantLock还可以实现公平锁和非公平锁的机制,通过构造方法传入不同的参数即可。ReentrantLock还提供了Condition对象,可以在某个条件满足时进行等待或唤醒线程。 synchronized是Java中的关键字,可以用于实现线程同步。使用synchronized关键字时,需要在方法或代码块前加上关键字synchronized。当某个线程进入synchronized方法或代码块时,会自动获取对象的锁,其他线程会被阻塞直到锁被释放。相比ReentrantLocksynchronize不需要显式地获取和释放锁,也不需要处理异常情况。此外,synchronize是非重入锁,即同一个线程再次获取同一个锁时会被阻塞。 总体而言,ReentrantLock提供了更强大、灵活和可靠的线程同步机制,然而使用ReentrantLock需要更多的代码控制和异常处理。而synchronize则更为简单,在一些简单的场景下可以更方便地实现线程同步。根据实际需求和场景的不同,可以选择适合的机制进行线程同步。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值