JUC练习1——synchronized和lock的简单使用回顾
1,注意:线程就是一个单独的资源类,没有任何附属的操作:例如现在有一个ticket类用于记录火车票,已经卖票的方法,这个ticket类就是资源类。多个线程去操控这个资源类的买票方法,最终实现卖票。
代码示例如下:
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class JucTest { public static void main(String[] args) { Tickets ticket = new Tickets(); // for (int j = 1; j < 4; j++) // { // new Thread(() -> // { // for (int i = 1; i < 60; i++) { // ticket.sell1(); // } // }, "A" + j).start(); // } for (int j = 1; j < 4; j++) { new Thread(() -> { for (int i = 1; i < 60; i++) { ticket.sell2(); } }, "B" + j).start(); } } } class Tickets { private int number1 = 50; private int number2 = 50; Lock lock = new ReentrantLock();//默认是可以插队的非公平锁,如果想要公平锁,参数为true //使用synchronized来实现并发,synchronized可以锁当前对象 synchronized void sell1() { if (number1 >0) { System.out.println(Thread.currentThread().getName()+"卖出了第"+ number1--+"张票"+" 剩余票数"+ number1); } } void sell2() { lock.lock();//上锁 //lock.tryLock();//尝试获取锁,当其它线程处于阻塞状态时使用 try { if (number1 >0) { System.out.println(Thread.currentThread().getName()+"卖出了第"+ number1--+"张票"+" 剩余票数"+ number1); } } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock();//释放锁 } } }2,synchronized和lock的区别 lock是一个类,synchronized是一个关键字 lock必须手动释放锁,synchronized会自动释放锁 lock可以获取锁的状态,synchronized是无法获取锁的状态的 占用lock锁的线程一旦阻塞了,其它线程可以使用trylock方法来获取锁,synchronized中一旦一个线程阻塞了,其它线程就只能一直等待下去 lock是可重入锁,默认是非公平的,synchronized的非公平的不可修改 lock适合锁大量的同步代码,synchronized适合锁少量的同步代码 补充: 1,java是无法创建一个线程的,它是调用native方法通过c++创建线程的 2,获取CPU的核数:(有多少个内核就有多少个线程可以并行执行)System.out.println(Runtime.getRuntime().availableProcessors()); 3,并发编程的本质:充分利用CPU 4,线程六大状态:创建new,运行run,阻塞blocked,等待waiting,超时等待timed_out,终止terminated。 5,wait和sleep方法的区别 1,来源不同:wait来自object类,sleep类中Thread类,工作中我们一般使用TimeUnit.DAYS.sleep(1);来进行sleep操作。 2,持有锁不同:wait会释放锁,sleep不会 3,使用范围不同:sleep在任何地方都可以用,wait只能在synchronized同步代码块中使用 4,是否需要捕获异常:wait不需要,sleep需要