线程同步

    大纲

     一、同步线程

 

   同步线程

     线程的运行时多个线程同时运行,哪一个线程先抢占到CPU资源,哪一个就先执行,那么这多个线程在操作同一个资源时,当线程就绪的时候加入休眠,就可能会出现不同步的现象。

     范例:观察问题

package cn.txp.thread.demo;
public class ThreadDemo05 implements Runnable{
    private String name;
    private int ticket; 
    public ThreadDemo05(String name, int ticket) {
        this.name = name;
        this.ticket = ticket;
    }
    @Override
    public void run() {
        for(int i = 0 ; i < 100; i ++) {
            if(ticket > 0) {
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程" + name + this.ticket --);
            }
        }
    }
    public static void main(String[] args) {
        ThreadDemo05 thread = new ThreadDemo05("线程", 5);
        new Thread(thread).start();
        new Thread(thread).start();
        new Thread(thread).start();
    }
}
// 运行结果

线程线程4
线程线程3
线程线程5
线程线程2
线程线程1
线程线程0
线程线程-1

 

 

 

    上面的代码我在运行线程时,加入了判断ticket必须要大于0,但是此时在执行线程前加入了延迟,多个线程同时去抢占资源的时候就会出现其他线程还没有对这个变量进行递减操作,而其他线程就已经完成了递减,这样就会造成负数问题。

    线程的同步就是在同一个时间内,只允许一个线程进行操作。需要等待当前线程执行完毕之后,其他的线程方可执行。

    线程同步两种方案:

      1、同步代码块

      2、同步方法  

    synchronized(this) { // 同步代码块的格式
            // 同步的代码
        }

 

 

 

    同步代码块范例:

package cn.txp.thread.demo;
public class ThreadDemo05 implements Runnable{
    private String name;
    private int ticket; //
    public ThreadDemo05(String name, int ticket) {
        this.name = name;
        this.ticket = ticket;
    }
    @Override
    public void run() {
        for(int i = 0 ; i < 100; i ++) {
            synchronized (this) {
                if(ticket > 0) {
                    try {
                        Thread.sleep(300);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("线程" + name + this.ticket --);
                }
            }
        }
    }
    public static void main(String[] args) {
        ThreadDemo05 thread = new ThreadDemo05("线程", 5);
        new Thread(thread).start();
        new Thread(thread).start();
        new Thread(thread).start();
    }
}

 

 

 

    同步方法范例

 

package cn.txp.thread.demo;
public class ThreadDemo06 implements Runnable{
    private String name;
    private int ticket; //
    public ThreadDemo06(String name, int ticket) {
        this.name = name;
        this.ticket = ticket;
    }
    @Override
    public void run() {
        for(int i = 0 ; i < 100; i ++) {
            this.sale();
        }
    }
    // 同步方法
    public synchronized void sale() {
        if(ticket > 0) {
            try {
                Thread.sleep(300);
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("线程" + name + this.ticket --);
        }
    }
    public static void main(String[] args) {
        ThreadDemo06 thread = new ThreadDemo06("线程", 5);
        new Thread(thread).start();
        new Thread(thread).start();
        new Thread(thread).start();
    }
}

 

 

 

     知乎文章: https://www.zhihu.com/people/tan-xu-peng-44


     编程专业知识:https://www.cnblogs.com/tjava


     编程开发技术问题解决CSDN:https://blog.csdn.net/qq_37291829

posted @ 2020-09-15 00:09  谭旭鹏  阅读(145)  评论(0)    收藏  举报