多线程第五旅

    xiaoxiao2022-07-07  181

    4.线程同步问题

    同步问题:每一个线程对象轮番抢占共享资源带来的问题(针对多线程问题)

     

    package www.wl.java;class MyThread implements Runnable {     private int ticket = 10 ; // 一共十张票    @Override     public void run() {         while(this.ticket>0) { // 还有票            try {                Thread.sleep(200);            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            } // 模拟网络延迟            System.out.println(Thread.currentThread().getName()+",还有" +this.ticket -- +" 张票");        }    }}public class Test {     public static void main(String[] args) {        MyThread mt = new MyThread() ;         new Thread(mt,"黄牛A").start();         new Thread(mt,"黄牛B").start();         new Thread(mt,"黄牛C").start();    }}

     

    结果: 黄牛C,还有10 张票 黄牛B,还有8 张票 黄牛A,还有9 张票 黄牛C,还有7 张票 黄牛B,还有5 张票 黄牛A,还有6 张票 黄牛C,还有4 张票 黄牛B,还有2 张票 黄牛A,还有3 张票 黄牛B,还有1 张票 黄牛A,还有0 张票 黄牛C,还有-1 张票

    Process finished with exit code 0  

     

     

     

    这个时候我们发现,票数竟然出现负数,这种问题我们称之为不同步操作。

    不同步的唯一好处是处理速度快(多个线程并发执行)

    4.1同步处理

    4.1.1使用synchronized(对象锁)关键字来处理同步问题

    synchronized处理同步有两种模式:同步代码块,同步方法

     

    同步代码块:要使用同步代码块必须要设置一个锁定的对象,一般可以锁定当前对象this,表示同一时刻只有一个线程能够进入同步代码块,但是多个线程可以同时进入方法

    代码如下:package www.wl.java;class MyThread implements Runnable { // 线程主体    private int  ticket=10;     @Override     public void run() {        for(int i=0;i<10;i++){            //为程序上锁            synchronized (this){                if(this.ticket>0) {                    try {                        Thread.sleep (200);                     } catch (InterruptedException e) {                        // TODO Auto-generated catch block                        e.printStackTrace ();                     } // 模拟网络延迟                    System.out.println (Thread.currentThread ().getName () + ",还有" + this.                             ticket-- + " 张票");                 }            }        }    }}public class test {    public static void main(String[] args) {        MyThread mt = new MyThread() ;         new Thread(mt,"黄牛A").start();         new Thread(mt,"黄牛B").start();         new Thread(mt,"黄牛C").start();     }}

    结果:

    黄牛A,还有10 张票

    黄牛A,还有9 张票

    黄牛C,还有8 张票

    黄牛C,还有7 张票

    黄牛B,还有6 张票

    黄牛C,还有5 张票

    黄牛A,还有4 张票

    黄牛C,还有3 张票

    黄牛B,还有2 张票

    黄牛C,还有1 张票

     

     

     

     

    同步方法:在方法中使用synchronized关键字,表示此方法只有一个线程能够进入。隐式锁对象,this

    代码如下:

      package www.bit.java;class MyThread implements Runnable { // 线程主体    private int  ticket=100;     @Override     public void run() {        for(int i=0;i<100;i++) {            sale ();         } }    //表示此方法只有一个线程能够进入    public synchronized void sale(){            if(ticket>0) {            System.out.println (Thread.currentThread ().getName () + ",还有" + this.ticket-- + " 张票");            }        }    }public class 多线程 {    public static void main(String[] args) {        MyThread mt = new MyThread() ;         new Thread(mt,"黄牛A").start();         new Thread(mt,"黄牛B").start();         new Thread(mt,"黄牛C").start();     }}

     

    关于synchronized的对象锁概念,里面锁个对象

    Synchronized(this)以及普通的synchronized方法,只能防止多个线程执行同一对象的同步段,synchronized锁的是括号中的对象而非代码

    全局锁:锁代码段

    1.synchronized与static一起使用,此时锁的是当前使用的类而非对象

    2.在代码块中锁当前Class对象

    Synchronized(Sync.class)即:(类名称.class){}

    最新回复(0)