今日学んだ主な内容:
1.synchronized关键字
2.volatile关键字
同期されたキーワード(同期):
synchronized关键字用来声明临界区(java线程中的关键代码块),临界区可以防止多个线程同时使用造成的麻烦。
当一个线程调用了临界区,别的线程不能访问除非调用结束。俗称加锁。
synchronized它拥有两种使用的方式:
synchronized方法:
加在方法名前是修饰实例方法将锁加在方法上。
通过修饰静态方法将锁加在类上。
synchronized块
揮発性キーワード(変更可能):
它只能修饰类的成员变量!(实例、静态的都可)
使用volatile域会导致线程使用主空间(内存)同步他的工作空间。
volatile并不是意味着“原子性”:
如果i是volatile,多个线程调用例如i++的操作就不是线程安全操作,我们需要
知道i++是多个语句的缩写。
SynchronizedTest01クラス(テストロックインスタンス):
package LessonForThread06;
public class SynchronizedTest01
{
public synchronized void method01()
{
for (int i=0; i<5; i++)
{
try
{
Thread.sleep(500);
} catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("This is method01 -- "+i);
}
}
public synchronized void method02()
{
for (int i=0; i<5; i++)
{
try
{
Thread.sleep(500);
} catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("This is method02 -- "+i);
}
}
public synchronized static void method03()//此时锁的是类!不是实例!
{
for (int i=0; i<5; i++)
{
try
{
Thread.sleep(500);
} catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("This is static -- "+i);
}
}
public static void main(String[] args)
{
SynchronizedTest01 s1 = new SynchronizedTest01();
// Thread t1 = new Thread(s1::method01);//用方法引用
// Thread t2 = new Thread(()->s1.method01());//用lambda表达式
// t1.start();
// t2.start();
// //此时method01方法有序的被两个线程分别调用,没有杂乱无章。
Thread t3 = new Thread(s1::method01);
Thread t4 = new Thread(SynchronizedTest01::method03);
t3.start();
t4.start();
// Thread t5 = new Thread(SynchronizedTest01::method03);
// t5.start();
}
}
SynchronizedTest02クラス(テストロッククラス):
package LessonForThread06;
public class SynchronizedTest02
{
public void method01()
{
synchronized (this)//制作一个同步代码块this表示当前实例!
{
for (int i=0; i<5; i++)
{
try
{
Thread.sleep(500);
} catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("This is method01 -- "+i);
}
}
}
public void method02()
{
synchronized (this)//锁在字符串上了
{
for (int i=0; i<5; i++)
{
try
{
Thread.sleep(500);
} catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("This is method02 -- "+i);
}
}
}
public void method03()
{
synchronized ("zlm")//制作一个同步代码块this表示当前实例!
{
for (int i=0; i<5; i++)
{
try
{
Thread.sleep(500);
} catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("This is method03 -- "+i);
}
}
}
public static void main(String[] args)
{
SynchronizedTest02 s = new SynchronizedTest02();
//s被锁定
Thread t1 = new Thread(s::method01);
Thread t2 = new Thread(s::method02);
Thread t3 = new Thread(s::method03);
t1.start();
t2.start();
t3.start();
//这个同步代码块锁定的是本类的实例。
//多个线程访问同一个实例的时候,必须得互相排队!
//而method03此时s没有被锁定,所以会和别的线程交叉出现!!
//因为此时锁定的不是方法是类的实例。
}
}
本篇部分文字来源于:
咕嘟咖啡杨海滨老师 — 《java编程语言高级特性》
在这里十分感谢老师能够给我带来学习的激情。
2020.10.24程序员节快乐!
可以转载我的学习日记但请注明出处,谢谢。
本文章是本人学习笔记,不进行任何商用!也请别拿去商用!只为记录本人学习历程。
毕