java多进程 -CD7-孙鑫-(4)-同步方法,同步块,售票例子
来源:互联网 发布:小提琴 曲 知乎 编辑:程序博客网 时间:2024/05/29 03:30
本节主要包含使用内部类来实现与使用Runnable接口实现线程一样的效果,还包含一个小例子售票来引出同步机制:同步块和同步方法
使用实现Runnable方法好处有两条:
- 如果你的MyThread类已经继承了一个类,那么java中不允许多继承,这样让你的MyThread实现一个Runnable接口正好啊。
- 如果同一个对象创建多线程那么共享一个数据成员index
使用内部类同样可以实现使用Runnable的两条好处
class MultiThread{ public static void main(String[] args) { MyThread myThread = new MyThread(); //如果创建多个线程但是是同一个对象,那么他们共享一个index //new Thread(myThread).start(); //new Thread(myThread).start(); //new Thread(myThread).start(); //new Thread(myThread).start(); //new Thread(myThread).start(); myThread.getThread().start(); myThread.getThread().start(); myThread.getThread().start(); myThread.getThread().start(); //设置为后台线程 //myThread.setDaemon(true); //设置优先级 //myThread.setPriority(Thread.MAX_PRIORITY); //myThread.start(); //int index = 1; while(true) { //if(index++ == 1000) //break; //获取当前的线程并且获取它的名字 System.out.println("main方法所在的线程的名字:" + Thread.currentThread().getName()); } }}class MyThread //implements Runnable//extends Thread{ int index = 0; class InnerThread extends Thread { public void run() { while(true) { //内部类可以访问外部类的成员 System.out.println(Thread.currentThread().getName() + ":" + index++); //将当前线程暂停 //yield(); } } } //隐藏实现细节 Thread getThread() { return new InnerThread(); } //run方法是线程的入口函数 /*public void run() { while(true) { System.out.println(Thread.currentThread().getName() + ":" + index++); //将当前线程暂停 //yield(); } }*/ }
联系模拟火车票售票系统
public static void sleep (long millis, int nanos)
线程的同步
The code segments within a program that access the same object from separate, concurrent threads are called “critical sections”。
在一个程序当中代码段访问了同一个对象从单独的并发的线程当中,那么这个代码段叫”临界区”
使用同步的机制对临界区进行保护
同步的两种方式:同步块和同步方法
对于同步来说都是使用synchronized方法
每一个对象都有一个监视器,或者叫做锁。
同步块示例
//C:\Users\Administrator\Documents\GitHubpackage ticket;class Tickets { public static void main(String[] args) { sellTickets st = new sellTickets(); //四个线程同时卖这100张票,注意是同一个对象创建四个线程,他们共享同一个变量ticket new Thread(st).start(); new Thread(st).start(); new Thread(st).start(); new Thread(st).start(); }}class sellTickets implements Runnable{ int ticket = 100; Object o = new Object(); @Override public void run() { while(true) { //每一个对象都有一个监视器,或者叫做锁。同步块示例 synchronized (o) { if(ticket > 0) { //存在的隐藏的问题当ticket=1,它的时间片到期了进入到if语句中,第二个线程进入到if语句然后时间片到期 try { //线程睡眠,该方法需要写异常 Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } //第几个线程卖出了第多少张票 System.out.println(Thread.currentThread().getName() + "sell tickets" + ticket); ticket--; } } } }}
同步方法示例
//C:\Users\Administrator\Documents\GitHubpackage ticket;class Tickets { public static void main(String[] args) { sellTickets st = new sellTickets(); //四个线程同时卖这100张票,注意是同一个对象创建四个线程,他们共享同一个变量ticket new Thread(st).start(); new Thread(st).start(); new Thread(st).start(); new Thread(st).start(); }}class sellTickets implements Runnable{ int ticket = 100; Object o = new Object(); @Override public void run() { while(true) { sell(); } } public synchronized void sell() { if(ticket > 0) { //存在的隐藏的问题当ticket=1,它的时间片到期了进入到if语句中,第二个线程进入到if语句然后时间片到期 try { //线程睡眠,该方法需要写异常 Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } //第几个线程卖出了第多少张票 System.out.println(Thread.currentThread().getName() + "sell tickets" + ticket); ticket--; } }}
同步方法利用的是this所代表的对象加的锁。
示例:分别使用同步块和同步方法来实现正确的结果
当同步块利用this所代表的对象synchronized (this)时就和同步方法使用的锁一致了
//C:\Users\Administrator\Documents\GitHubpackage ticket;class Tickets { public static void main(String[] args) { sellTickets st = new sellTickets(); // 四个线程同时卖这100张票,注意是同一个对象创建四个线程,他们共享同一个变量ticket new Thread(st).start(); //为什么写sleep因为当我们main时间片没有消耗完,不会执行new Thread(st).start()(第一个)那么st.b = true;赋值执行了并且赋值成功,当main 时间片消耗完再来执行new Thread(st).start()(第一个),此时已经是为false了,所以写sleep 是为了让主线程睡一会 try{ Thread.sleep(1); }catch(Exception e){ e.printStackTrace(); } st.b = true; new Thread(st).start(); }}class sellTickets implements Runnable { int ticket = 100; Object o = new Object(); //定义一个boolean变量让同步块和同步方法分别执行 public boolean b = false; @Override public void run() { if (b == false) { while (ticket > 0) { try { // 线程睡眠,该方法需要写异常 Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } //false时执行同步方法 sell(); } } else { //当true时执行同步块 while (ticket > 0) { try { // 线程睡眠,该方法需要写异常 Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (this) { if(ticket > 0){ // 第几个线程卖出了第多少张票 System.out.println("obj" + Thread.currentThread().getName() + "sell tickets" + ticket); ticket--; } } } } } public synchronized void sell() { if(ticket > 0){ // 第几个线程卖出了第多少票号的张票 System.out.println("sell:" + Thread.currentThread().getName() + "sell tickets" + ticket); ticket--; } }}
结果:
sell:Thread-0sell tickets10
objThread-1sell tickets9
sell:Thread-0sell tickets8
objThread-1sell tickets7
sell:Thread-0sell tickets6
objThread-1sell tickets5
sell:Thread-0sell tickets4
objThread-1sell tickets3
sell:Thread-0sell tickets2
objThread-1sell tickets1
下节预告
每个class也有一个锁,是这个class所对应的Class对象的锁。
- java多进程 -CD7-孙鑫-(4)-同步方法,同步块,售票例子
- java多线程实现火车售票系统 以及java中的同步的实现 同步块 和同步方法同时 同步
- java多进程 -CD7-孙鑫-(5)
- java同步方法和同步代码块
- java同步方法和同步代码块
- java同步方法和同步代码块
- java 线程方法同步和同步块
- 同步方法与同步块
- java线程同步方法,方法块区别
- java多进程 -CD7-孙鑫-(1)-程序/进程/线程/设置后台线程/将当前线程暂停
- Java多线程4—线程同步问题+火车票售票系统
- Java多线程4—线程同步问题+火车票售票系统
- 线程同步的方法实现售票
- java多进程 -CD7-孙鑫-(2)-java对多线程的支持,深入理解
- java同步方法和同步代码块的区别
- Java中同步方法和同步代码块
- java同步方法和同步代码块的区别
- java多线程——同步方法和同步代码块
- 类型“System.ComponentModel.PropertyChangedEventManager”未标记为可序列化
- 链表(找中间+判循环+逆序+)
- 链表基本操作
- 集合中迭代器的2中方式
- POJ2118基础矩阵快速幂
- java多进程 -CD7-孙鑫-(4)-同步方法,同步块,售票例子
- 第四周 项目二:对象作为数据成员
- What Is 'SSL'? What Is 'SSH'?
- Android中开发Service
- [笔记]hadoop2.4.1伪分布式集群搭建\hdfs入门
- [LeetCode]Find Minimum in Rotated Sorted Array
- C语言指针说明
- [Python] Python两个内置函数——locals 和globals
- 接口的使用与多态性