Java 锁的使用

volatile 修饰元素,保证可见性,不保证原子性。
++a 不是原子操作。

给++a加锁
创建原子类,每次自增1
List和Vector

public class SyDemoA1 {
    volatile List<String> list = new ArrayList<>();
    Vector<String> vec = new Vector<>();
    int sum = 0;
    AtomicInteger nn = new AtomicInteger(0);


    public static void main(String[] args) {
        var t = new SyDemoA1();
        var t1 = new Thread(t::add, "T1");
        var t2 = new Thread(t::add, "T2");
        var t3 = new Thread(t::add, "T3");
        t1.start();
        t2.start();
        t3.start();
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (Exception e) {
            e.printStackTrace();
        }


        System.out.println(t.list.size());
        System.out.println(t.vec.size());
        System.out.println(t.sum);
        System.out.println(t.nn.get());
    }

    void add() {
        String t = Thread.currentThread().getName();
        for (int i = 0; i < 10000; i++) {
            synchronized (this) {
                sum++;
            }
            nn.incrementAndGet();
            list.add("Item-" + t + "-" + i);
            vec.add("Item-" + t + "-" + i);

        }
        System.out.println(t + "结束");
    }
}

显示锁的使用,需要手动上锁和解锁

public class ReentrantDemo {


    ReentrantLock lock = new ReentrantLock();

    public static void main(String[] args) {
        ReentrantDemo rd = new ReentrantDemo();
        var t1 = new Thread(rd::m, "T1");
        var t2 = new Thread(rd::m, "T2");
        t1.start();
        t2.start();
    }

    void m() {
        String t = Thread.currentThread().getName();
        System.out.println(t + "线程运行");
        for (int i = 0; i < 10; i++) {
            lock.lock();
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
            System.out.println(t + ":" + i);
        }
    }

死锁模拟

public class ThreadA2 {
    Object a = new Object();
    Object b = new Object();

    public static void main(String[] args) {
        ThreadA2 t = new ThreadA2();
        var t1 = new Thread(t::m1, "T1");
        var t2 = new Thread(t::m2, "T2");
        t1.start();
        t2.start();
    }

    void m1() {
        String t = Thread.currentThread().getName();
        System.out.println(t + "线程运行");
        synchronized (a) {
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            synchronized (b) {

            }
        }
        System.out.println("线程结束");
    }

    void m2() {
        String t = Thread.currentThread().getName();
        System.out.println(t + "线程运行");
        synchronized (b) {
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            synchronized (a) {

            }
        }
        System.out.println("线程结束");
    }
}

线程监控,10个一打印

public class MonitorDemoA1 {
    CountDownLatch latch = new CountDownLatch(1);
    Vector<Integer> vector = new Vector<>();
    Random rand = new Random();

    public static void main(String[] args) {

        MonitorDemoA1 t = new MonitorDemoA1();
        var t1 = new Thread(t::adda1, "add");

        boolean a = false;
        boolean finalbool1 = false;
        Callable<Boolean> call = () -> {
            return t.counta1(finalbool1);
        };
        FutureTask<Boolean> ft = new FutureTask<>(call);
        var c = new Thread(ft, "count");
        t1.start();
        c.start();
        try {
            a = ft.get();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (a) {
            t1.interrupt();
        }
    }

    void adda1() {
        String tn = Thread.currentThread().getName();
        System.out.println(tn + "线程启动");
        while (true) {
            try {
                Thread.sleep(500);
            } catch (Exception e) {
                //e.printStackTrace();
                System.out.println("线程退出");
                break;

            }
            System.out.println("已经添加一个元素");
            vector.add(rand.nextInt(1, 101));
            if (vector.size() == 10) {
                latch.countDown();
            }
        }
    }

    boolean counta1(boolean a) {
        String tn = Thread.currentThread().getName();
        System.out.println(tn + "监控线程启动");
        try {
            latch.await();
            System.out.println("容器已到10个");
            a = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return a;
    }
}

方法二:不好,但也能用

public class MonitorDemoA2 {
    static AtomicInteger nn = new AtomicInteger(0);
    Object o = new Object();

    public static void main(String[] args) {
        MonitorDemoA2 t = new MonitorDemoA2();
        var t1 = new Thread(t::adda1, "add");
        var t2 = new Thread(t::counta1, "count");
        t1.start();
        //t2.setDaemon(true);
        t2.start();
    }

    void adda1() {
        String tn = Thread.currentThread().getName();
        System.out.println(tn + "线程启动");
        while (true) {

            try {
                Thread.sleep(500);
            } catch (Exception e) {
                e.printStackTrace();
            }
            nn.incrementAndGet();
            System.out.println("执行一次" + nn.get());
        }
    }

    void counta1() {
        String tn = Thread.currentThread().getName();
        System.out.println(tn + "监控线程启动");
        while (true) {
            if (nn.get() % 10 == 0) {
                System.out.println("容器已到10个");
            }
            try {
                Thread.sleep(400);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }
}

注意时间,待修改

门闩类的使用

public class ThreadA1 {
    static List<Integer> list = new ArrayList<>();
    static CountDownLatch latch = new CountDownLatch(2);
    Random rand = new Random();

    public static void main(String[] args) {
        ThreadA1 t = new ThreadA1();
        var t1 = new Thread(t::adda1, "T1");
        var t2 = new Thread(t::adda1, "T2");
        t1.start();
        t2.start();
        try {
            latch.await();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(list);
    }

    void adda1() {
        String t = Thread.currentThread().getName();
        for (int i = 0; i < 10; i++) {
            int a = rand.nextInt(0, 101);
            list.add(a);
            System.out.println(t + "线程添加了" + a);
        }
        latch.countDown();
    }

}
wait() sleep() notifyAll()
在锁中:

wait()等待时会释放锁,里面不填写时间时会进入阻塞状态,只有等待notify()和notifyAll()唤醒,一般notify()只唤醒一个,而notifyAll()会唤醒所有wait()的线程。
sleep() notifyAll()时不会释放锁。

interrupt()打断

打断 执行指令时会产生异常,打断线程。

public static void main(String[] args) {
        var t = new Thread(() -> {
            String tn = Thread.currentThread().getName();
            while (true) {
                try {
                    Thread.sleep(1000);
                    System.out.println(tn + "已经休眠1秒");
                } catch (Exception e) {
                    //e.printStackTrace();
                    break;
                }
            }
        }, "T1");
        t.start();

        try {
            Thread.sleep(4000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("中断线程");
        t.interrupt();
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值