线程八锁学习
1、锁的东西就三个
对象和Class和自己定义的Object
2、锁的具体使用
这里用同步方法举例的
2.1 同一个类里面两个普通的 synchronized 方法
/**
*
* 这个类中的两个方法用的都是同一个锁
*
*/
public class WindowSell5 {
public synchronized void sendMsg() throws InterruptedException{
TimeUnit.SECONDS.sleep(4);
System.out.println("sendMsg");
}
public synchronized void call(){
System.out.println("打电话");
}
}
/**
*
* 两个线程两个方法,先打印那个 先打印sendmsg 然后打印打电话。
* windowSell5 中的两个方法用的是同一个锁,锁是对象
* 两个锁谁先拿到谁执行。所以a线程先执行,即使说sendMsg 执行比较耗时,b线程也不会执行
* a线程和b线程用的是同一个锁,你用了我就不能用了,只有你释放了我才能拿到锁。所以说b线程一直会等待
*
*/
public class WindowSell5Test {
public static void main(String[] args) throws InterruptedException{
WindowSell5 windowSell5 = new WindowSell5();
new Thread(()->{
try {
windowSell5.sendMsg();
}catch (Exception e){
}
},"a").start();
//如果这里不sleep 下 线程b也可能执行
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
windowSell5.call();
},"b").start();
}
}
2.2同一个类里面一个synchronized 方法、一个普通的方法
/**
*
* 这个类中的一个方法有锁一个没有锁
*
*/
public class WindowSell1 {
public synchronized void sendMsg() throws InterruptedException{
TimeUnit.SECONDS.sleep(4);
System.out.println("sendMsg");
}
public void hello(){
System.out.println("hello");
}
}
/**
* 两个线程两个方法,先打印那个 打电话
*
* a 线程执行后比较耗时4s,同时有把锁,锁 是 方法的调用者就是windowSell1 这个对象
* 而线程b 没有锁,不存在锁的争抢,b 线程一看,你忙着呢,我就不等你了我就执行了。
*
*
*
*
*
*
*/
public class WindowSell1Test {
public static void main(String[] args) throws Exception{
WindowSell1 windowSell1 = new WindowSell1();
new Thread(()->{
try {
windowSell1.sendMsg();
}catch (Exception e){
}
},"a").start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
windowSell1.hello();
},"b").start();
}
}
2.3 同一个类里面两个用static 修饰的 synchronized 方法
public class WindowSell3 {
public static synchronized void sendMsg() throws InterruptedException{
TimeUnit.SECONDS.sleep(4);
System.out.println("sendMsg");
}
public static synchronized void call(){
System.out.println("打电话");
}
}
/**
*
* WindowSell3 中的两个方法 sendMsg call 都有锁,有一个共同的锁,锁是WindowSell3
* 所以线程a 执行的时候,线程b需要等待
*
* 即使说new 两个对象 一个执行 sendMsg 一个执行call 也是线程先打印 sendmsg 然后打印 打电话
*
*
*
*/
public class WindowSell3Test {
public static void main(String[] args) throws InterruptedException{
WindowSell3 windowSell3 = new WindowSell3();
WindowSell3 windowSell3_1 = new WindowSell3();
new Thread(()->{
try {
windowSell3.sendMsg();
}catch (InterruptedException i){
}
},"a").start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
//windowSell3.call();
windowSell3_1.call();
},"b").start();
}
}
2.4 同一个类里面一个用static 修饰的 synchronized 方法,一个不用static 修饰的 synchronized 方法
public class WindowSell4 {
public static synchronized void sendMsg() throws InterruptedException{
TimeUnit.SECONDS.sleep(4);
System.out.println("sendMsg");
}
public synchronized void call(){
System.out.println("打电话");
}
}
/**
*
*
* 两个线程两个方法,先打印那个 b线程
* WindowSell4 中的两个方法 sendMsg call 都有锁,sendMsg 这个方法的锁是类WindowSell4
* 而call 这个方法的锁是 对象,两个方法两把锁。
* 所以说 先打印 打电话
*
*/
public class WindowSell4Test {
public static void main(String[] args) throws InterruptedException{
WindowSell4 windowSell4 = new WindowSell4();
new Thread(()->{
try {
windowSell4.sendMsg();
}catch (Exception e){
}
},"a").start();
//如果这里不sleep 下 线程b也可能执行
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
windowSell4.call();
},"b").start();
}
}
3、同步代码块的使用
public class WindowSell5 {
public void sendMsg(){
synchronized (WindowSell5.class){
try {
TimeUnit.SECONDS.sleep(3);
}catch (InterruptedException e){
}
System.out.println("sendMsg");
}
}
public void call(){
synchronized (this){
try {
TimeUnit.SECONDS.sleep(2);
}catch (InterruptedException e){
}
System.out.println("打电话");
}
}
public void hello(){
String s = "hello";
synchronized (s){
System.out.println("hello");
}
}
}
public class MainTest1 {
public static void main(String[] args) {
WindowSell5 windowSell5 = new WindowSell5();
/**
*
* 1、hello 先执行,其次是call,其次是sendMsg
* 2、三个不同的锁
*/
new Thread(()->{
windowSell5.sendMsg();
},"a").start();
new Thread(()->{
windowSell5.call();
},"b").start();
new Thread(()->{
windowSell5.hello();
},"c").start();
}
}

浙公网安备 33010602011771号