黑马程序员技术交流社区

标题: JavaSE多线程与线程同步以及对象锁 [打印本页]

作者: 逆风TO    时间: 2020-2-12 16:53
标题: JavaSE多线程与线程同步以及对象锁
在使用java多线程的时候如果着多个线程访问的是同一个共享数据;

例如售票, 多个售票点线程各自售票, 但都是从一个地方取票, 这就会造成操作系统让多个线程能够"同时"访问这个共享数据, 所谓同时并不是真正意义上的同时,而是很短间隔;

只是这个线程不能一次性执行完它的线程体, 比如说它现在只拿到了共享变量的值, 但是还没有做修改,

但是这时很可能会由于cpu分配给自己的时间片用完了而进入阻塞状态, 这时候另一个线程开始, 并且成功的拿到了并且修改了这个共享变量,的值;

很显然他们俩拿到的是同一个值,这就是问题所在.
于是线程同步就提出来了;
而线程同步又是基于对象锁的;
一般用对象锁更灵活;
未加线程代码:

package MultiThread;

public class TicketSellTest{
        public static void main(String[] args) {
                System.out.println("main线程开始");
                TicketOffice tick = new TicketOffice();
                Thread s1 = new Thread(tick);
                Thread s2 = new Thread(tick);
                Thread s3 = new Thread(tick);
                s1.setName("售票点1 ");
                s2.setName("售票点2 ");
                s3.setName("售票点3 ");
                s1.start();
                s2.start();
                s3.start();
                System.out.println("main线程结束");
        }
}

class TicketOffice implements Runnable{
        // 售出的票计数器
        private int tickets = 0;
        // 不管用这个类创立多少个线程, 每个线程执行start()的时候只执行run()方法
        public void run() {
                boolean flag = true;
                while(flag) {
                        flag = sell();
                }
        }
        // 售票方法
        private boolean sell() {
                boolean flag = true;
                if (tickets < 10) {
                        tickets = tickets + 1;
                        // 获取正在执行这里的线程对象的引用的名字, 即是获取正在执行这里的线程名字
                        System.out.println(Thread.currentThread().getName() + "卖出第 "+tickets +" 张票");
                }else {
                        System.out.println("无票可卖!!");
                        flag = false;
                }
                // 为了增大出错几率, 让线程停留一会儿
                try {
                        Thread.sleep(300);
                }catch(InterruptedException e) {
                        System.out.println("售卖过程中出现InterruptedException");
                        e.printStackTrace();
                }
                // 返回True表示有票可卖
                return flag;
        }
}
// 执行结果
// 可以看到这里就是由于不加限制访问共享变量造成的后果, 就是一个线程没有完成一个完整的操作, 就被另一个线程介入了
main线程开始
售票点1 卖出第 2 张票
main线程结束
售票点2 卖出第 2 张票
售票点3 卖出第 3 张票
售票点1 卖出第 4 张票
售票点2 卖出第 6 张票
售票点3 卖出第 6 张票
售票点1 卖出第 7 张票
售票点2 卖出第 8 张票
售票点3 卖出第 9 张票
售票点1 卖出第 10 张票
无票可卖!!
无票可卖!!
无票可卖!!

然后解决办法是进行线程同步,此处有两个方法:
第一个

//将sell()方法变成一个同步方法,即在方法定义的时候加入synchronized修饰符
//如下
private synchronized boolean sell(){}
//这会使得此方法为同步方法,作用是每次线程执行此方法不会被打断,一定要执行完

还有一个方法是将操作共享变量的那一块代码变成同步代码块,即用synchronized(this){}将操作共享变量的那段代码包围起来;
其中括号里的参数表示获取制定对象的对象锁;
如下:


        // 售票方法
        private  boolean sell() {
                boolean flag = true;
                // 加入同步代码块,这个this表示调用此方法的对象的引用;获取此对象的对象锁
                synchronized(this) {
                        if (tickets < 10) {
                                tickets = tickets + 1;
                                // 获取正在执行这里的线程对象的引用的名字, 即是获取正在执行这里的线程名字
                                System.out.println(Thread.currentThread().getName() + "卖出第 "+tickets +" 张票");
                        }else {
                                System.out.println("无票可卖!!");
                                flag = false;
                                }
                }
                // 为了增大出错几率, 让线程停留一会儿
                try {
                        Thread.sleep(300);
                }catch(InterruptedException e) {
                        System.out.println("售卖过程中出现InterruptedException");
                        e.printStackTrace();
                }
                // 返回True表示有票可卖
                return flag;
        }
//这样的运行结果就不会有冲突,如下
main线程开始
售票点1 卖出第 1 张票
售票点2 卖出第 2 张票
main线程结束
售票点3 卖出第 3 张票
售票点1 卖出第 4 张票
售票点2 卖出第 5 张票
售票点3 卖出第 6 张票
售票点1 卖出第 7 张票
售票点2 卖出第 8 张票
售票点3 卖出第 9 张票
售票点1 卖出第 10 张票
无票可卖!!
无票可卖!!
无票可卖!!

对象锁

同步机制的实现就是利用了对象锁;

JVM对每一个对象都有一个对象锁; 这个对象锁代表任何时候只允许一个线程能够有访问权限;

即是如果线程获取了这个对象的对象锁, 那么在它释放之前这段时间里面其他线程都不能访问;

其作用和synchronized同步机制是一样的,但是这个对象锁用起来更为灵活;

java提供了一种显示加锁机制, 使用java.util.concurrent.locks.Lock接口提供的lock()方法来获取锁;

用unlock()方法解锁,通常使用ReentrantLock这个类来实现, 上面更改之处的示例如下:

// 对象锁的实现所依赖的包
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

        // 售票方法
        // 创建Lock锁实例
        private Lock lock = new ReentrantLock();
        private boolean sell() {
                boolean flag = true;
                // 获取对象锁
                lock.lock();
                if (tickets < 10) {
                        tickets = tickets + 1;
                        // 获取正在执行这里的线程对象的引用的名字, 即是获取正在执行这里的线程名字
                        System.out.println(Thread.currentThread().getName() + "卖出第 "+tickets +" 张票");
                }else {
                        System.out.println("无票可卖!!");
                        flag = false;
                        }
                // 释放锁
                lock.unlock();



作者: 孙丽    时间: 2020-3-3 11:45
6666666666666666
作者: 孙丽    时间: 2020-3-3 11:45
6666666666666666
作者: 孙丽    时间: 2020-3-3 11:47
6666666666666666
作者: zhanghua342    时间: 2020-3-3 11:49
厉害厉害
作者: zhaosongzhi    时间: 2020-3-3 12:08
改变是痛苦的,但成长的过程更是喜悦的,一定要加油!
作者: duanshaobo    时间: 2020-3-3 12:09
╭( ′• o •′ )╭☞就是这个人!
作者: sdjadyhm    时间: 2020-3-3 12:11
棒棒哒!
作者: zhaosongzhi    时间: 2020-3-3 12:15
改变是痛苦的,但成长的过程更是喜悦的,一定要加油!
作者: zhaosongzhi    时间: 2020-3-3 12:22
改变是痛苦的,但成长的过程更是喜悦的,一定要加油!
作者: 你不爱我    时间: 2020-3-3 12:29
感谢分享  学到了   很厉害              
作者: zhaosongzhi    时间: 2020-3-3 12:29
改变是痛苦的,但成长的过程更是喜悦的,一定要加油!
作者: 逆风TO    时间: 2020-3-3 13:47
感谢分享  加油哦
作者: Emmmmm~    时间: 2020-3-3 14:20
加油呢,感谢分享,撒花
作者: 章鱼顶呱呱    时间: 2020-3-3 14:34
66666666666666666666666
作者: 举个栗子    时间: 2020-3-3 15:15

作者: 大安    时间: 2020-3-3 16:41
改变是痛苦的,但成长的过程更是喜悦的,一定要加油!
作者: 殷凯老师    时间: 2020-3-3 17:32
棒棒哒,感谢分享
作者: 耙丫丫    时间: 2020-3-3 21:25
6666666666666666666666666666666
作者: fujiangbo    时间: 2020-3-4 08:44
键盘敲烂,月薪过万^_^^_^
作者: 王锦    时间: 2020-3-4 09:19
6666666666666666666666
作者: jsnoob    时间: 2020-3-4 09:21
加油加油加油!!!!
作者: 霍尔    时间: 2020-3-4 09:57
棒棒的
作者: json0314    时间: 2020-3-4 10:05
6666666666666666
作者: dendi    时间: 2020-3-4 10:34
感谢分享,加油加油。。。。。。
作者: 123木头人555    时间: 2020-3-4 10:40
66666666666666666666666
作者: 王微    时间: 2020-3-4 11:01
棒棒哒,感谢分享
作者: 哦嗨呦    时间: 2020-3-4 11:18
好人一生平安
作者: longyu3    时间: 2020-3-4 13:51
加油,努力,向上.........
作者: yujq    时间: 2020-3-4 13:52
66666666666666666
作者: 古城十六少    时间: 2020-3-4 16:59
学习了,感谢分享
作者: 宗进1    时间: 2020-3-4 18:13
太好了,加油
作者: 八戒猪    时间: 2020-3-4 18:17
膜拜大神
作者: 雨落轻舟    时间: 2020-3-4 20:13
条理清晰,再接再厉
作者: lvxinvip    时间: 2020-3-4 20:29

作者: 爱笑的姑娘    时间: 2020-3-4 21:08
6666666666666666666666666666
作者: 黑马程序员啊    时间: 2020-3-4 21:27
感谢分享  学到了   很厉害  
作者: 零度☆黎明    时间: 2020-3-4 22:14
6666666666666666666666666
作者: zplxwl    时间: 2020-3-4 22:17
6666666666666
作者: kdhdjdj    时间: 2020-3-5 14:19

棒棒哒,感谢分享
作者: 1467584    时间: 2020-3-5 14:39
666666666666666666666666666666666666
作者: hello!!!    时间: 2020-3-5 14:52

作者: 小公举    时间: 2020-3-5 16:43
感谢楼主的分享
作者: 我是小圆圆    时间: 2020-3-5 16:52

键盘敲烂,月薪过万^_^^_^
作者: 半个程序员    时间: 2020-3-5 17:11
6666666666666666
作者: 九月丫    时间: 2020-3-5 17:16
6666666666666666666666666666666666666666666
作者: lzq123    时间: 2020-3-5 18:55
6666666666666666666666666666666
作者: hongping    时间: 2020-3-6 10:06
感谢分享  加油哦~
作者: daoqin    时间: 2020-3-6 10:22
就业篇,面试时我们应该保持怎样的一个心态
作者: 我爱我1022    时间: 2020-3-6 10:47
棒棒的,加油
作者: 素问    时间: 2020-3-6 10:52
感谢分享,加油~!
作者: 逆风TO    时间: 2020-3-9 09:36
孙丽 发表于 2020-3-3 11:45
6666666666666666

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:36
耙丫丫 发表于 2020-3-3 21:25
6666666666666666666666666666666

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:36
fujiangbo 发表于 2020-3-4 08:44
键盘敲烂,月薪过万^_^^_^

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:36
耙丫丫 发表于 2020-3-3 21:25
6666666666666666666666666666666

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:36
zhaosongzhi 发表于 2020-3-3 12:22
改变是痛苦的,但成长的过程更是喜悦的,一定要加油!

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:36
殷凯老师 发表于 2020-3-3 17:32
棒棒哒,感谢分享

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:36
殷凯老师 发表于 2020-3-3 17:32
棒棒哒,感谢分享

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:36
孙丽 发表于 2020-3-3 11:45
6666666666666666

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:36
章鱼顶呱呱 发表于 2020-3-3 14:34
66666666666666666666666

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:36
你不爱我 发表于 2020-3-3 12:29
感谢分享  学到了   很厉害

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:36
sdjadyhm 发表于 2020-3-3 12:11
棒棒哒!

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:37
zhaosongzhi 发表于 2020-3-3 12:22
改变是痛苦的,但成长的过程更是喜悦的,一定要加油!

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:37
大安 发表于 2020-3-3 16:41
改变是痛苦的,但成长的过程更是喜悦的,一定要加油!

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:37
你不爱我 发表于 2020-3-3 12:29
感谢分享  学到了   很厉害

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:38
Emmmmm~ 发表于 2020-3-3 14:20
加油呢,感谢分享,撒花

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:38
zhaosongzhi 发表于 2020-3-3 12:29
改变是痛苦的,但成长的过程更是喜悦的,一定要加油!

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:38
逆风TO 发表于 2020-3-3 13:47
感谢分享  加油哦

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:38
殷凯老师 发表于 2020-3-3 17:32
棒棒哒,感谢分享

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:38
耙丫丫 发表于 2020-3-3 21:25
6666666666666666666666666666666

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:38
Emmmmm~ 发表于 2020-3-3 14:20
加油呢,感谢分享,撒花

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:38
逆风TO 发表于 2020-3-9 09:36
感谢支持  加油加油!

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:38
duanshaobo 发表于 2020-3-3 12:09
╭( ′• o •′ )╭☞就是这个人!

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:38
Emmmmm~ 发表于 2020-3-3 14:20
加油呢,感谢分享,撒花

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:38
逆风TO 发表于 2020-3-3 13:47
感谢分享  加油哦

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:39
Emmmmm~ 发表于 2020-3-3 14:20
加油呢,感谢分享,撒花

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:39
孙丽 发表于 2020-3-3 11:45
6666666666666666

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:39
fujiangbo 发表于 2020-3-4 08:44
键盘敲烂,月薪过万^_^^_^

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:39
耙丫丫 发表于 2020-3-3 21:25
6666666666666666666666666666666

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:39
大安 发表于 2020-3-3 16:41
改变是痛苦的,但成长的过程更是喜悦的,一定要加油!

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:39
fujiangbo 发表于 2020-3-4 08:44
键盘敲烂,月薪过万^_^^_^

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:39
逆风TO 发表于 2020-3-9 09:39
感谢支持  加油加油!

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:39
章鱼顶呱呱 发表于 2020-3-3 14:34
66666666666666666666666

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:39
zhanghua342 发表于 2020-3-3 11:49
厉害厉害

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:39
fujiangbo 发表于 2020-3-4 08:44
键盘敲烂,月薪过万^_^^_^

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:40
duanshaobo 发表于 2020-3-3 12:09
╭( ′• o •′ )╭☞就是这个人!

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:40
殷凯老师 发表于 2020-3-3 17:32
棒棒哒,感谢分享

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:40
sdjadyhm 发表于 2020-3-3 12:11
棒棒哒!

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:40
逆风TO 发表于 2020-3-3 13:47
感谢分享  加油哦

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:40
zhaosongzhi 发表于 2020-3-3 12:08
改变是痛苦的,但成长的过程更是喜悦的,一定要加油!

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:40
孙丽 发表于 2020-3-3 11:47
6666666666666666

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:40
孙丽 发表于 2020-3-3 11:47
6666666666666666

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:41
举个栗子 发表于 2020-3-3 15:15

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:41
大安 发表于 2020-3-3 16:41
改变是痛苦的,但成长的过程更是喜悦的,一定要加油!

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:41
大安 发表于 2020-3-3 16:41
改变是痛苦的,但成长的过程更是喜悦的,一定要加油!

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:41
耙丫丫 发表于 2020-3-3 21:25
6666666666666666666666666666666

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:41
孙丽 发表于 2020-3-3 11:47
6666666666666666

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:41
孙丽 发表于 2020-3-3 11:45
6666666666666666

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:41
殷凯老师 发表于 2020-3-3 17:32
棒棒哒,感谢分享

感谢支持  加油加油!
作者: 逆风TO    时间: 2020-3-9 09:41
zhaosongzhi 发表于 2020-3-3 12:08
改变是痛苦的,但成长的过程更是喜悦的,一定要加油!

感谢支持  加油加油!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2