/*** 多线程共享数据* 线程同步:多个线程在同一个时间段只能有一个线程执行其指定代码,其他线程要等待此线程完成之后才可以继续执行。* 多线程共享数据的安全问题,使用同步解决。* 线程同步两种方法:* 1.同步代码块*      synchronized(要同步的对象){ 要同步的操作 }* 2.同步方法*      public synchronized void method(){ 要同步的操作 }*/
public class Main {public static void main(String[] args) {MyThread s0 = new MyThread();Thread t1 = new Thread(s0,"one");Thread t2 = new Thread(s0,"two");t1.start();t2.start();}
}class MyThread implements Runnable{Object obj = new Object(); //同步的标记对象
    @Overridepublic void run() {//同步代码块synchronized(obj){System.out.println(Thread.currentThread().getName()+" is doing...");try {Thread.sleep(1000);} catch (InterruptedException ex) {ex.printStackTrace();}System.out.println(Thread.currentThread().getName()+" finished.");}}
}

public class Main {public static void main(String[] args) {MyThread s0 = new MyThread();Thread t1 = new Thread(s0,"one");Thread t2 = new Thread(s0,"two");t1.start();t2.start();}
}class MyThread implements Runnable{@Overridepublic void run() {doMethod();}/*** 同步方法,同步的是当前对象(this)*/public synchronized void doMethod(){System.out.println(Thread.currentThread().getName()+" is doing...");try {Thread.sleep(1000);} catch (InterruptedException ex) {ex.printStackTrace();}System.out.println(Thread.currentThread().getName()+" finished.");}
}/*** 同步代码会带来性能降低的问题,担高数据的安全性* 当编写synchronized块时,有几个简单准则可以遵循。* 1.使代码块保持简短,把不随线程变化的预处理和后处理移出synchronized块。* 2.不要阻塞。如InputStream.read()。* 3.在持有锁的时候,不要对其它对象调用方法。*/

/*** 线程死锁:同步过多,会造成死锁*/
public class Main {public static void main(String[] args) {new MyThread();}
}class MyThread implements Runnable{Customer c = new Customer();Waiter w = new Waiter();public MyThread(){new Thread(this).start();w.say(c);}@Overridepublic void run() {c.say(w);}
}class Customer{ //顾客public synchronized void say(Waiter w){System.out.println("顾客说:先做再给钱!");w.doService();}public synchronized void doService(){System.out.println("顾客同意了,先给钱再做");}
}
class Waiter{ //服务员public synchronized void say(Customer c){System.out.println("服务员说:先给钱再做!");c.doService();}public synchronized void doService(){System.out.println("服务员同意了,先做再给钱");}
}//Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。 //1.当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。//2.然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。//3.尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。//4.第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。//5.以上规则对其它对象锁同样适用。

/*** 生产者与消费者应用案例:生产者不断生产产吕,消费者不断取走产品。* sleep与wait的区别:sleep不释放对象锁,wait释放对象锁。*/
public class Main {public static void main(String[] args) {Food f = new Food();Productor p = new Productor(f);Consumer c = new Consumer(f);new Thread(p).start();new Thread(c).start();}
}class Productor implements Runnable{ //生产者:厨师
    Food food;public Productor(Food f){this.food = f;}@Overridepublic void run() {for(int i=0;i<100;++i){if(i%2==0){food.set("西红柿炒蛋"+i, "补充维生素C。"+i);}else{food.set("胡萝卜炒肉"+i, "补充维生素A。"+i);}}}
}
class Consumer implements Runnable{ //消费者:服务员
    Food food;Consumer(Food f){this.food = f;}@Overridepublic void run() {for(int i=0;i<100;++i){food.get();}}
}
class Food{String name;String content;boolean flag = true; //true可以生产,false可以拿走public synchronized void set(String name,String content){ //生产产品if(!flag){try {this.wait(); //让当前线程进入等待池等待,没有指定时间,需要其它线程唤醒//释放对象锁,让出CPU} catch (InterruptedException ex) {ex.printStackTrace();}}this.name = name;try {Thread.sleep(300);} catch (InterruptedException ex) {ex.printStackTrace();}this.content = content;flag = false;this.notify(); //唤醒在该监视器上的一个线程
    }public synchronized void get(){ //消费产品if(flag){try {this.wait(); //让当前线程进入等待池等待,没有指定时间,需要其它线程唤醒//释放对象锁,让出CPU} catch (InterruptedException ex) {ex.printStackTrace();}}try {Thread.sleep(300);} catch (InterruptedException ex) {ex.printStackTrace();}System.out.println(this.name+":"+this.content);flag = true;this.notify(); //唤醒在该监视器上的一个线程
    }
}

/*** 线程池是预先创建线程的一种技术。线程池在还没有任务到来之前,创建一定数量的线程,放入空闲队列中,* 然后对这些资源进行复用。减少频繁的创建和销毁对象。*/
public class Main {public static void main(String[] args) {MyThread t1 = new MyThread();MyThread t2 = new MyThread();MyThread t3 = new MyThread();//创建一个单线程的线程池ExecutorService es = Executors.newSingleThreadExecutor(); es.execute(t1);es.execute(t2);//创建一个固定大小的线程池ExecutorService es2 = Executors.newFixedThreadPool(2);es2.execute(t1);es2.execute(t2);es2.execute(t3);//创建一个可缓存的线程池ExecutorService es3 = Executors.newCachedThreadPool();es3.execute(t1);es3.execute(t2);//创建一个大小无限的线程池ExecutorService es4 = Executors.newScheduledThreadPool(2);es3.execute(t1);es3.execute(t2);}
}class MyThread implements Runnable{@Overridepublic void run() {for(int i=0;i<10;++i){try {Thread.sleep(1000);} catch (InterruptedException ex) {ex.printStackTrace();}System.out.println("MyThread-"+i);}}
}

转载于:https://www.cnblogs.com/fish7/p/4174719.html

JAVA笔记14__多线程共享数据(同步)/ 线程死锁 / 生产者与消费者应用案例 / 线程池...相关推荐

  1. java调用kafka接口发送数据_Java调用Kafka生产者,消费者Api及相关配置说明

    本次的记录内容包括: 1.Java调用生产者APi流程 2.Kafka生产者Api的使用及说明 3.Kafka消费者Api的使用及说明 4.Kafka消费者自动提交Offset和手动提交Offset ...

  2. Java学习(7):同步问题之生产者与消费者的问题

    生产者生产馒头,消费者消费馒头.一个篮子,生产者往篮子中放馒头,消费者从篮子中取馒头. /*** 这是一个篮子类** @author xcx* @time 2017年7月21日上午10:01:32*/ ...

  3. 【Python网络编程和并发-多线程共享数据混乱引出同步锁】

    38_第五章-多线程共享数据混乱引出同步锁 一.上节回顾 总结 在一个进程内的所有线程共享全局变量,能够在部使用其他方式的前提下完成多线程之间的数据共享(这点要比多进程更好) 缺点就是,线程对全局变量 ...

  4. java多线程同步与死锁_浅析Java多线程中的同步和死锁

    Value Engineering 1基于Java的多线程 多线程是实现并发机制的一种有效手段,它允许编程语言在程序中并发执行多个指令流,每个指令流都称为一个线程,彼此间相互独立,且与进程一样拥有独立 ...

  5. JAVA 笔记 10 多线程

    进程 与 线程 进程 进程资源分配的最小单位,CPU从磁盘中读取一段程序到内存中,该执行程序的实例就叫做进程; 一个程序如果被CPU多次读取到内存中,则变成多个独立的进程. 线程 线程是程序执行的最小 ...

  6. python进阶12并发之八多线程与数据同步

    原创博客地址:python进阶12并发之八多线程与数据同步 python并发首选进程,但偶尔有场景进程无法搞定,比如有些变量是无法序列化的,就无法使用工具包manager()的工具类进行共享.如果自己 ...

  7. Request和Response-学习笔记02【请求转发和request共享数据、Request_获取ServletContext、request登录案例】

    Java后端 学习路线 笔记汇总表[黑马程序员] Request和Response-学习笔记01[Request_原理和继承体系.Request_获取请求数据][day01] Request和Resp ...

  8. java的知识点34——线程通信 || 生产者与消费者问题

    线程通信 应用场景:生产者和消费者问题 • 假设仓库中只能存放一件产品,生产者将生产出来的产品放入仓库,消费者将仓库中产品取走消费 • 如果仓库中没有产品,则生产者将产品放入仓库,否则停止生产并等待, ...

  9. java线程-从生产者和消费者模型说起

    今天学习了经典的生产者和消费者模型,引起了对java线程等知识的一系列的思考. 在平时的编程中,经常遇到一个线程要产生数据,而另一个线程要处理产生出来的数据,这其实就是生产者和消费者的关系.生产者在产 ...

最新文章

  1. 2019年《计算机应用基础》,2019年自考《计算机应用基础》模拟练习及答案一
  2. python arcade库是干什么的-Python街机模块arcade的鼠标移动与单击示例
  3. putty颜色设置|securecrt颜色设置|windows命令行颜色设置
  4. 到国外使用wifi悠着点防止天价帐单
  5. OpenStack部署之小结
  6. mysql 目录更改 php,Linux下更改MySQL目录
  7. Java语言程序设计(基础篇) 第十一章 继承和多态
  8. python day 10
  9. dev c 编程语言,devc如何自定义头文件并使用
  10. ssm企业人事管理系统
  11. qq游戏大厅 for linux,网友第一时间抢先评测:腾讯QQ Linux版
  12. 南京信息工程大学python期末考试_南京信息工程大学的雷丁学院怎么样?
  13. 未来是机器人还是人类的天下?
  14. 【AWS云从业者基础知识笔记】——模块4:网络
  15. 预处理命令不是c语言本身的组成部分,C中的预处理命令
  16. 基于PaddleSpeech搭建个人语音听写服务
  17. ES聚合查询详解(四):管道聚合
  18. 2016年4月编程语言排行榜 Visual Basic正渐行渐远
  19. Android权限(permission)大全
  20. 神都夜行录无法显示服务器,神都夜行录这款手游都有哪些渠道服?神都夜行录服务器汇总介绍...

热门文章

  1. zookeeper节点类型详解
  2. oracle数据库教程-张晨光-专题视频课程
  3. Struts2标签库和OGNL
  4. linux shell命令行及脚本编程实例详解_超全整理!这些Shell编程必备知识你都掌握了吗?...
  5. MappedByteBuffer以及ByteBufer的底层原理
  6. 学习ModSecrity Handbook之摘录
  7. 20-forEach循环语句
  8. HashMap Hashtable区别
  9. Win10+Anaconda环境下安装PyTorch
  10. java ip地址相关操作