Java中同步机制有一下几种方式(3种)

线程同步的机制是用来解决线程安全问题的
操作同步代码时,只能有一个线程参与,其他线程等待。相当于是一个单线程的过程,效率低。

标题1、Java中同步机制有一下几种方式

1.1、方式一:同步代码块(处理实现Runnable安全问题,Thread实现类实现的话,需要加static保证当前对象的唯一性)

synchronized(同步监视器){
//需要被同步的代码
}
说明: 1、操作共享数据的代码,即为需要被同步的代码
2、共享数据:多个线程共同操作的变量。比如:ticket就是共享数据。
3、同步监视器:俗称锁。任何一个类的对象,都可以充当锁。
要求: 多个线程必须要公用同一把锁

案例(窗口取票案例):

class Windows implements Runnable{
private int tickets = 100;
private Object ob = new Object(); //线程的同一把锁,即同一个对象
    @Override
    public void run() {
        while (true) {
            synchronized(ob) {  //通过synchronized来加锁  
                if (tickets > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + ":买票,票号为:" + tickets);
                    tickets--;
                } else {
                    break;
                }
            }
        }
    }
}
public class Window {
    public static void main(String[] args) {
        Windows w = new Windows();
        Thread t1 = new Thread(w);
        Thread t2 = new Thread(w);
        Thread t3 = new Thread(w);
      
        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");
        t1.start();
        t2.start();
        t3.start();
    }
}

1.2、方式二:同步方法

关于同步方法总结:
1、同步方法仍然涉及到同步监器,只是不需要我门显示的声明。
2、非静态同步方法,同步监视器是this
静态的同步方法,同步监视器是:当前类本身
当使用Thread类的子类时,需要把同步方法设置为static public static synchronized void way()

class Windows implements Runnable{
    private int tickets = 100;
    @Override
    public void run() {
        while (true) {
            way();
        }
    }
    public synchronized void way() {  //通过synchronized来加锁,代表的是this当前的Windows类
        if (tickets > 0) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + ":买票,票号为:" + tickets);
            tickets--;
        }
    }
}
public class Window {
    public static void main(String[] args) {
        Windows w = new Windows();
        Thread t1 = new Thread(w);
        Thread t2 = new Thread(w);
        Thread t3 = new Thread(w);
        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");
        t1.start();
        t2.start();
        t3.start();
    }
}

1.3、Lock()锁 ————JDK5.0新增

import java.util.concurrent.locks.ReentrantLock;
class Windowt implements Runnable {
    private int ticktes = 100;
    private ReentrantLock lock = new ReentrantLock();
    @Override
    public void run() {
        while (true) {
            try{
                //加放锁
                lock.lock();
                if (ticktes > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "当前的票数为:" + ticktes);
                    ticktes--;
                } else {
                    break;
                }
            }finally {
                //释放锁
                lock.unlock();
            }
        }
    }
}
public class ThreadLock {
    public static void main(String[] args) {
        Windowt window = new Windowt();
        Thread t1 = new Thread(window);
        Thread t2 = new Thread(window);
        Thread t3 = new Thread(window);
        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");
        t1.start();
        t2.start();
        t3.start();
    }
}
发布了62 篇原创文章 · 获赞 21 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/lsy_666/article/details/105128764