首页 > 技术文章 > Java synchronized 线程同步

huanggy 2018-08-23 14:45 原文

同步方法

class MyTheard4 implements Runnable{

    private int ticket;

    public MyTheard4(int ticket) {
        this.ticket = ticket;
    }

    public int getTicket() {
        return ticket;
    }

    public void setTicket(int ticket) {
        this.ticket = ticket;
    }

    @Override
    public void run() {
        // test 方法是同步方法, 一次只能一个线程进入. 但是循环会有多个线程同时进入
        while (this.getTicket() > 0){
            test();
        }
    }
    // 同步方法
    public synchronized void test(){
        // 1, 当剩余 1 张票的时候, 还是会有多个线程进入循环, 都等在同步方法外面
        // 2, 这里再次判断就不会出现 0 或负数的情况
        if (this.getTicket() <= 0){
            return;
        }
        System.out.println(Thread.currentThread().getName() + ": " + ticket);
        ticket--;
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
public class Test4 {
    public static void main(String[] args) {
        MyTheard4 myTheard4 = new MyTheard4(10);
        new Thread(myTheard4, "线程A").start();
        new Thread(myTheard4, "线程B").start();
        new Thread(myTheard4, "线程C").start();
        new Thread(myTheard4, "线程D").start();
        new Thread(myTheard4, "线程E").start();
    }
}

同步代码块

  在同步方法的基础上修改 test() 方法, 当然也可以直接把同步代码块直接写在线程体里( run() 方法里面 )

    1, 方法去掉 synchronized 关键字

    2, 方法体使用 synchronized 关键字包裹起来

public void test() {
    // 同步代码块
    synchronized (this) {
        if (this.getTicket() <= 0) {
            return;
        }
        System.out.println(Thread.currentThread().getName() + ": " + ticket);
        ticket--;
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

 

推荐阅读