Java 多线程, 同步访问, 线程锁,锁对象,ReentrantLock,synchronized

1.为什么要同步访问数据?

  当两个或以上的线程需要共享对同一数据的存取,可能会发生共享数据的讹误。

2.实现同步的方式

  2.1 ReentrantLock类

    School类:

        class School{

            private int stuNum;
            private Lock lock;
private Condition condition;

            public School(int stuNum) {
                this.stuNum = stuNum;
                lock = new ReentrantLock();
                condition = lock.newCondition();
            }
        ......

    其中 lock是锁对象, condition 是条件对象,

    用法:

        public void stuNums1(){
            lock.lock();
            try{
                while (stuNum < 20){
                    System.out.println(stuNum+" < 20,等待数量变为20");
                    condition.await();
                }
                stuNum -= 5;
                System.out.println(Thread.currentThread().toString() + ":" + stuNum);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }

        }
        public void stuNums2(){
            lock.lock();
            try{
                stuNum += 1;
                System.out.println(Thread.currentThread().toString() + ":" + stuNum);
                if (stuNum >= 20){
                    System.out.println(stuNum + ">20了,开始唤醒等待集的线程");
                    condition.signalAll();
                }
            } finally {
                lock.unlock();
            }

        }

    当条件对象调用await()方法时候,当前线程会进入等待集,处于阻塞状态,直到其他线程在同一条件上调用signalAll()方法为止。

原文地址:https://www.cnblogs.com/lovleo/p/11318623.html

时间: 2024-10-13 17:12:26

Java 多线程, 同步访问, 线程锁,锁对象,ReentrantLock,synchronized的相关文章

java基础知识回顾之java Thread类学习(六)--java多线程同步函数用的锁

1.验证同步函数使用的锁----普通方法使用的锁 思路:创建两个线程,同时操作同一个资源,还是用卖票的例子来验证.创建好两个线程t1,t2,t1线程走同步代码块操作tickets,t2,线程走同步函数封装的代码操作tickets,同步代码块中的锁我们可以指定.假设我们事先不知道同步函数用的是什么锁:如果在同步代码块中指定的某个锁(测试)和同步函数用的锁相同,就不会出现线程安全问题,如果锁不相同,就会发生线程安全问题. 看下面的代码:t1线程用的同步锁是obj,t2线程在操作同步函数的资源,假设不

java多线程同步以及线程间通信详解&amp;消费者生产者模式&amp;死锁&amp;Thread.join()(多线程编程之二)

本篇我们将讨论以下知识点: 1.线程同步问题的产生 什么是线程同步问题,我们先来看一段卖票系统的代码,然后再分析这个问题: [java] view plain copy print? package com.zejian.test; /** * @author zejian * @time 2016年3月12日 下午2:55:42 * @decrition 模拟卖票线程 */ public class Ticket implements Runnable { //当前拥有的票数 private 

Java多线程-同步:synchronized 和线程通信:生产者消费者模式

大家伙周末愉快,小乐又来给大家献上技术大餐.上次是说到了Java多线程的创建和状态|乐字节,接下来,我们再来接着说Java多线程-同步:synchronized 和线程通信:生产者消费者模式. 一.同步:synchronized 多个线程同时访问一个对象,可能造成非线程安全,数据可能错误,所谓同步:就是控制多个线程同时访就是控制多线程操作同一个对象时,注意是同一个对象,数据的准确性, 确保数据安全,但是加入同步后因为需要等待,所以效率相对低下. 如:一个苹果,自己一个人去咬怎么都不会出问题,但是

转:关于JAVA多线程同步

转:http://lanvis.blog.163.com/blog/static/26982162009798422547/ 因为需要,最近关注了一下JAVA多线程同步问题.JAVA多线程同步主要依赖于若干方法和关键字.将心得记录如下: 1  wait方法:        该方法属于Object的方法,wait方法的作用是使得当前调用wait方法所在部分(代码块)的线程停止执行,并释放当前获得的调用wait所在的代码块的锁,并在其他线程调用notify或者notifyAll方法时恢复到竞争锁状态

Java多线程之后台线程不执行finally

后台线程不执行finally package wzh.daemon; import java.util.concurrent.TimeUnit; class ADaemon implements Runnable { @Override public void run() { try { System.out.println("Starting ADaemon"); TimeUnit.SECONDS.sleep(1); } catch (Exception e) { System.ou

Java多线程之后台线程

将线程设置成后台线程Daemons 主线程结果后,后台线程将自动结果. package wzh.test; import java.util.concurrent.TimeUnit; class SimpleDaemons implements Runnable{ @Override public void run() { try { while (true) { TimeUnit.MILLISECONDS.sleep(100); System.out.println(Thread.curren

java 内部类如何访问外部类的对象

用this就可以做到 实例如下: package innerclass; /** * 内部类如何得到外部类的对象 *  * */ public class DotThis { public class Inner { //返回外部内的对象 public DotThis outer(){ return DotThis.this; } } public void print(){ System.out.println("Out class"); } /** * 得到内部内的对象 */ pu

Java多线程---同步与锁

一,线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏. 二.同步和锁定 1.锁的原理 Java中每个对象都有一个内置锁. 当程序运行到非静态的synchronized同步方法上时,自动获得与正在执行代码类的当前实例(this实例)有关的锁.获得一个对象的锁也称为获取锁.锁定对象.在对象上锁定或在对象上同步. 当程序运行到synchronized同步方法或代码块时该对象锁才起作用. 一个对象只有一个锁.所以,如果一个线程获得该锁,就没有其他线程可以获得锁,直到第一个线程释放(或返回

Java多线程同步锁的理解

ava 多线程中同步锁的主要通过synchronized的关键字来实现的.让我们从一个买票程序说起吧. package com.day04; /** * * @author Administrator 问题描述:使用多线程的方式来模拟多个窗口买票 * */ public class SaleWindow implements Runnable { // 初始化票数10 private int ticket = 10; @Override public void run() { // 获取线程的名