java多线程 读取变量同步安全的案例

本次介绍,我使用的是synchronized 同步代码块的关键字来读取list,在写java多线程时,一定要注意
synchronized 关键字的有效范围。
ps:
如果synchronized 关键字的代码块范围太大,可能会导致 优先获取到cpu资源的第一个线程 在满足条件的情况下 一直无法跳循环,从而使得其他线程
无法给获取到被cpu调度的机会,造成:想“多线程执行代码块”的预期-》演变成了 “单线程一路走到黑 执行代码块”的惨象,也就是让多线程的预期 实际变成了单线程了。
以下 我就用1个错误的例子,和一个正确的例子给大家介绍以下吧:
1.错误的例子:实际是单线程 执行synchronized代码块的内容:
package com.cdncp.testautomation.control.schedule;

public class SellTicketTest {
    public static void main(String[] args) {
        for(int i=0;i<9;i++){
            TicketSell t1 = new TicketSell();
            t1.setName(""+i+"号窗口");
            t1.start();
        }
//        TicketSell t1 = new TicketSell();
//        TicketSell t2 = new TicketSell();
//        TicketSell t3 = new TicketSell();
//        TicketSell t4 = new TicketSell();
//
//        t1.setName("第一号窗口");
//        t2.setName("第二号窗口");
//        t3.setName("第三号窗口");
//        t4.setName("第四号窗口");
//
//        t1.start();
//        t2.start();
//        t3.start();
//        t4.start();
    }
}

第二个类:

package com.cdncp.testautomation.control.schedule;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TicketSell extends Thread {
    private static int ticket = 20;
    private static final Lock lock = new ReentrantLock();

    @Override
    public void run() {
//        System.out.println(this.getName() + "卖出第 " + ticket + "号票");
        System.out.println(this.getName() + "卖出第 " + ticket + "号票");
        while (true) {
            synchronized (TicketSell.class) {
                if (ticket > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
//                synchronized (TicketSell.class) {
                    if (ticket > 0) {
                        ticket--;
                        System.out.println(this.getName() + "---------------------卖出第 " + ticket + "号票");
                    }

//                }
                } else {
                    System.out.printf("%s:票已售空 \n", Thread.currentThread().getName());
                    break;
                }
            }
        }
    }


}

执行结果:

 

2.正确的例子:实现多线程 执行synchronized代码块的内容:
package com.cdncp.testautomation.control.schedule;

public class SellTicketTest {
    public static void main(String[] args) {
// 方法一:创建9个线程
        for(int i=0;i<9;i++){
            TicketSell t1 = new TicketSell();
            t1.setName(""+i+"号窗口");
            t1.start();
        }
// 方法二:创建9个线程
//        TicketSell t1 = new TicketSell();
//        TicketSell t2 = new TicketSell();
//        TicketSell t3 = new TicketSell();
//        TicketSell t4 = new TicketSell();
//
//        t1.setName("第一号窗口");
//        t2.setName("第二号窗口");
//        t3.setName("第三号窗口");
//        t4.setName("第四号窗口");
//
//        t1.start();
//        t2.start();
//        t3.start();
//        t4.start();
    }
}
package com.cdncp.testautomation.control.schedule;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TicketSell extends Thread {
    private static int ticket = 20;
    private static final Lock lock = new ReentrantLock();

    @Override
    public void run() {
//        System.out.println(this.getName() + "卖出第 " + ticket + "号票");
        System.out.println(this.getName() + "卖出第 " + ticket + "号票");
        while (true) {
            if (ticket > 0) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (TicketSell.class) {
                    if (ticket > 0) {
                        ticket--;
                        System.out.println(this.getName() + "---------------------卖出第 " + ticket + "号票");
                    }

                }
            } else {
                System.out.printf("%s:票已售空 \n", Thread.currentThread().getName());
                break;
            }
        }
    }

}

 

执行结果:

 

posted @ 2024-04-17 15:21  苹果芒  阅读(7)  评论(0编辑  收藏  举报