java11_线程的同步
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java11_线程的同步相关的知识,希望对你有一定的参考价值。
线程的同步---以三个窗口售票100张为例(1)问题:卖票的过程出现重票和错票
(2)原因:当某个线程操作车票的过程中,尚未操作完成,其他线程参与进来,也操作车票
(3)解决:当一个线程a在操作共享对象时,其他线程不能参与进来,直到线程a操作完毕,其他
线程才可以开始操作共享对象。
这种情况,即使线程a出现了阻塞,也不能被改变
(4)java中通过同步机制,来解决线程的安全问题:
方式一:同步代码块
synchronized(同步监视器){
//需要被同步的代码(操作共享数据的代码)
//共享数据:多个线程共同操作的变量
//不能包含太多,不也能包太少
}
同步监视器----俗称:锁,任何一个类的对象,都可以充当锁
要求:多个线程必须要共用同一把锁,唯一性
补充1:在实现Runnable接口中,使用this做同步监视器
class Window1 implements Runnable {
/*只创造了一个Window1对象,因此可以实现100张票共享*/
private int ticket=100;
Object ob=new Object();//任何一个类的对象,都可以充当锁
@Override
public void run() {
while(true){
synchronized(this) {//此时的this:唯一的window1对象,不用在另外创建一个类的对象
// synchronized(ob) {
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + "卖票:" + ticket);
ticket--;
} else {
break;
}
}
}
}
}
补充2:在继承Thread类创建多线程的方式中,使用 线程类.class 作为同步监视器,慎用this
class Window2 extends Thread{
private static int ticket=100;
private static Object obj=new Object();
@Override
public void run(){
while(true) {
// synchronized (obj) {
synchronized (Window2.class) {//类类型的对象也可以
// synchronized(this) {错误,在继承这种方法的时候不能写this,因为new的时候会产生多个对象
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (ticket > 0) {
System.out.println(getName() + "卖票:" + ticket);
ticket--;
}
}
}
}
}
}
方式二:同步方法
将需要进行同步的代码放在一个方法中,给方法加上synchronized
关于同步方法的总结:
①同步方法仍然涉及到同步监视器,只是不需要显示声明
②非静态的同步方法:同步监视器是:this
静态的同步方法:同步监视器是当前类的本身 类.class
1.用同步方法解决,实现Runnable接口创建多线程
class Window3 implements Runnable {
/*只创造了一个Window1对象,因此可以实现100张票共享*/
private int ticket=100;
@Override
public void run() {
while(true){
show();
}
}
private synchronized void show(){
if (ticket > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "卖票:" + ticket);
ticket--;
}
}
}
2.同步方法解决继承Thread类创建多线程
class Window4 extends Thread{
private static int ticket=100;
@Override
public void run(){
while(true) {
show();
}
}
private static synchronized void show(){//此时同步监视器:Window4.class
//private synchronized void show(){//同步监视器的对象不唯一,和new 有关
if (ticket > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "卖票:" + ticket);
ticket--;
}
}
}
使用同步机制的作用:
好处----同步的方式,解决了线程的安全问题
局限性----操作同步代码时,只能有一个线程参与,其他线程等待。相当于是一个单线程的过程,效率低
以上是关于java11_线程的同步的主要内容,如果未能解决你的问题,请参考以下文章
阶段1 语言基础+高级_1-3-Java语言高级_05-异常与多线程_第3节 线程同步机制_4_解决线程安全问题_同步代码块