Java基础-synchronized使用
来源:互联网 发布:最好的网络推广平台 编辑:程序博客网 时间:2024/06/08 15:30
多进程synchronized使用
1.synchronized解释
用于装饰【方法】或【代码块】,保证在同一时刻,多线程环境下,最多只有一个线程可以执行这个方法,当有一个线程执行该代码的时候对,线程进行上锁,执行完毕后释放锁,其他线程开始执行,执行流程类似生产者消费者模式
例子:
1.当有一个线程进入后,对线程计数器 +1
2.其他线程进入时,发现有线程正在执行,线程wait()
3.执行结束后唤醒其他线程,执行notify()方法
2.synchronized使用
//对文件进行读写public class NIOUtils { public static String read(String filename) throws IOException { FileInputStream fio = new FileInputStream(filename); //获取文件通道 FileChannel fc = fio.getChannel(); //分配缓冲区大小 ByteBuffer buffer = ByteBuffer.allocate((int)fc.size()); // 读取文件 fc.read(buffer); //获取字节数组 byte[] bt=buffer.array(); return new String(bt,0,(int)fc.size()); } public static void write(String filename, String content) throws IOException { FileOutputStream fio = new FileOutputStream (filename); //获取文件通道 FileChannel fc = fio.getChannel(); //分配缓冲区大小 ByteBuffer buffer = Charset.forName("utf8").encode(content); //buffer.flip(); fc.write(buffer); }}
//文件内容+1public class AddFileOne implements Runnable { private String filename = "C:\\download\\test.txt"; @Override public void run() { service(); } private void service(){ try { Thread.sleep(1000); String content = NIOUtils.read(filename); if(content==null||"".equals(content.trim())){ content = "0"; } Integer count = Integer.valueOf(content); System.out.println(count); count++; NIOUtils.write(filename, count.toString()); } catch (Exception e) { e.printStackTrace(); } }}
(1).开启多进程写入文件
public class Main1 { public static void main(String[] args) { AddFileOne add = new AddFileOne(); for (int i = 0; i < 100; i++) { Thread t = new Thread(add); t.start(); } }}
结果
010111报错报错
原因是因为多进程写统一文件报出异常
(2).修改代码运行
修改代码如:AddFileOne.java
public void run() { synchronized (this) { service(); } }
或把service方法添加synchronized
private synchronized void service(){
```结果
1
2
3
4
5
6
发现已经成功文件写入成功##3.使用问题###(1).代码块不同步修改Main1.java如下```javapublic class Main1 { public static void main(String[] args) { for (int i = 0; i < 100; i++) { AddFileOne add = new AddFileOne(); Thread t = new Thread(add); t.start(); } }}<div class="se-preview-section-delimiter"></div>
运行结果
00011001<div class="se-preview-section-delimiter"></div>
发现代码不同步了
(2).分析原因
这种情况表明,synchronized修饰符,仅仅只对同一个对象开启多线程后,执行某一个方法才进行锁,多个对象的相同方法执行多线时无法进行单线程执行
【java线程锁,只对对象生效,不对代码生效】
(2).解决方法1
修改AddFileOne.java为静态方法
private static synchronized void service(){<div class="se-preview-section-delimiter"></div>
结果
1234<div class="se-preview-section-delimiter"></div>
原因:
因为静态代码在整个工程中属于唯一,内存对象只有一个,同一时间只能一个进程在执行,这么做就是有点浪费资源
如果静态对象不加synchronized,多线程时可以访问的
(3).解决方法2
修改AddFileOne.java,给代码加统一的锁,如下
public class AddFileOne implements Runnable { String filename = "C:\\download\\test.txt"; private final Object lock; public AddFileOne(Object lock) { this.lock = lock; } @Override public void run() { synchronized (lock){ service(); } } private synchronized void service(){ try { String content = NIOUtils.read(filename); if(content==null||"".equals(content.trim())){ content = "0"; } Integer count = Integer.valueOf(content); System.out.println(count); count++; NIOUtils.write(filename, count.toString()); } catch (Exception e) { e.printStackTrace(); } }}<div class="se-preview-section-delimiter"></div>
Main1.java运行时传入线程锁
public class Main1 { public static void main(String[] args) { Object lock = new Object(); for (int i = 0; i < 100; i++) { AddFileOne add = new AddFileOne(lock); Thread t = new Thread(add); t.start(); } }}<div class="se-preview-section-delimiter"></div>
结果
12345
4.使用总结
1.synchronized只对对象起作用
2.synchronized static 是对某个类的静态对象方式对线程访问
3.synchronized方法和synchronized代码块一般没有区别,synchronized代码块更能精确访问
4.synchronized不能继承
0 0
- Java基础-synchronized使用
- Java基础---synchronized 详解
- JAVA基础--Synchronized
- JAVA基础--Synchronized
- java synchronized详解 | Java基础
- Java的synchronized使用
- java synchronized的使用
- java synchronized 使用
- java synchronized互斥锁使用
- java-synchronized 嵌套使用
- java Synchronized使用
- Java synchronized的使用
- java基础之synchronized用法
- 【java并发】基础(4)--synchronized
- 【Java基础】多线程之synchronized
- Java基础——synchronized
- JAVA基础——Java Synchronized
- Java中synchronized的使用
- Java语言基础(六)之 —— 选择结构(switch语句)
- Android属性动画完全解析(上),初识属性动画的基本用法
- Unity中HideInInspector和SerializeField
- 使用angularjs1.x构建前台开发框架(七)——弹窗【一】
- 回溯法,并用回溯法请求0/1背包问题和皇后问题
- Java基础-synchronized使用
- 二叉树链表表示法
- ROS学习(四)机器人的移动与矫正
- 十六周—结构体练习
- SHA-256算法实现
- 我的下载资源整理(持续更新)
- 【模板】字符串哈希
- Java中常用的比较器Comparable与Comparator
- linux基础命令——文本编辑vim