java 多线程“同步锁”
什么是多线程同步:
多个线程之间共享同一个资源。如果没有同步的话,多个线程就会出现异步,争CPU资源会出现数据错误,导致线程并发。有了同步后,可以实现数据的正确性。
同步锁:
同步锁中锁的是对象,不是方法或者是代码块。只有当一个线程停止时,另外一个线程才可以进入。这样可以保证数据同步,不会出现异步的情况。
同步方法:
synchronized关键字修饰的方法
public synchronized static boolean lock(){
boolean flag = false;
if (count>0){
flag = true;
System.out.println(Thread.currentThread().getName()+" "+"票数为"+(count--)+"号码");
}else {
flag = false;
}
return flag;
同步代码块
synchronized修饰的语句块
@Override
public void run() {
while (true){
synchronized (this){//this表示当前对象,此时表示创建的 sys1
if(count > 0){
try {
//模拟卖票需要一定的时间
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"售票,票号为:"+count--);
}
}
}
}
同步方法和同步代码块相比,同步代码块的效率比较高,而且同步代码块比较简洁,只需要一部分同步就行了。下面主要说的是同步代码块。
synchronized (this) // this表示当前的对象,这里的this就表示sys1
public static void main(String[] args) {
synchronize sys1 = new synchronize();
Thread thread1 = new Thread(sys1,"窗口一");
synchronized (synchronize.class) //这是同步整个类,将这个类中的对象都当做一个同步锁。下面代码虽然有两个对象,但是同步时整个类,把类中的所有对象都当做一个同步锁、
public static void main(String[] args) {
synchronize sys1 = new synchronize();
synchronize sys2 = new synchronize();
Thread thread1 = new Thread(sys1,"窗口一");
Thread thread2 = new Thread(sys2,"窗口二");
在实现同步时,只需要一把同步锁就行了,意思就是只需要一个对象就。还有当一个线程进入同步锁之后,其他线程处于阻塞状态,只有当当前进程停止后,其他的进程才可以进入。下面举个例子说:
在房间里有一个保险柜,同步锁就是保险柜锁,假如有四个人(四个线程)都持有一把打开这个保险柜锁的钥匙,当四个人中的其中一人把钥匙插入钥匙孔中,其他人的钥匙便不能再插入,只能等这个人把钥匙拔出来后,其他人的钥匙才能插入。(这就是当一个线程进入同步锁之后,其他线程处于阻塞状态,只有当当前进程停止后,其他的进程才可以进入)。现在假如保险柜有100块钱,这四个人的钥匙都是这个保险柜的钥匙,也就是说,只能在这个保险柜取钱,每当一个人取出10块,另外一个人取的时候,保险柜只能是90块,这就实现了资源共享和同步。
在多线程中,不同的对象有不同的同步锁。
像下面的代码,分别有sys1和sys2两个对象,这就会有两个同步锁。两个同步锁不能实现完全同步的情况,还是会出现异步的情况。
public class synchronize implements Runnable{
// 共享资源要全局变量
private static int count = 100;
@Override
public void run() {
while (true){
synchronized (this){//this表示当前对象,此时表示创建的 sys1
if(count > 0){
try {
//模拟卖票需要一定的时间
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"售票,票号为:"+count--);
}
}
}
}
//两个对象,有两个同步锁
public static void main(String[] args) {
synchronize sys1 = new synchronize();
synchronize sys2 = new synchronize();
Thread thread1 = new Thread(sys1,"窗口一");
Thread thread2 = new Thread(sys2,"窗口二");
thread1.start();
thread2.start();
}
}
输出结果:
从输出结果可以看出,数据并完全同步,出现了异步的情况。
正例:只有一个同步锁
public class synchronize implements Runnable{
// 共享资源要全局变量
private static int count = 100;
@Override
public void run() {
while (true){
synchronized (synchronize.class){//this表示当前对象,此时表示创建的 sys1
if(count > 0){
try {
//模拟卖票需要一定的时间
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"售票,票号为:"+count--);
}
}
}
}
public static void main(String[] args) {
synchronize sys1 = new synchronize();
Thread thread1 = new Thread(sys1,"窗口一");
Thread thread2 = new Thread(sys1,"窗口二");
Thread thread3 = new Thread(sys1,"窗口三");
Thread thread4 = new Thread(sys1,"窗口四");
thread1.start();
thread2.start();
thread3.start();
thread4.start();
}
}
输出结果:
从输出结果可以看出数据完全同步了。
我看过许多关于线程的博客,但是真心觉得整个博客写的好
https://www.cnblogs.com/riskyer/p/3263032.html