java程序开发实战教程电子版,System

文章探讨了Java中浅拷贝和深拷贝的区别,以System.arraycopy为例,通过二维数组和对象复制的示例解释深拷贝的概念。同时,文章分析了System.arraycopy在多线程环境下的线程安全性问题,并提供了相关代码示例和面试题资源链接。
摘要由CSDN通过智能技术生成

String[] obj4 = new String[5];

try {

System.arraycopy(obj3, 3, obj4, 3, 2);

} catch (Exception e) {

System.out.println(“transfer exception:”+e);

}

System.out.println(Arrays.toString(obj3));

//[null, null, null, 4, 5]

System.out.println(Arrays.toString(obj4));

obj3[3] = “zhangssan”;

System.out.println(“查看是浅复制还是深复制~~~~~”);

System.out.println(Arrays.toString(obj3));

System.out.println(Arrays.toString(obj4));

}

}

只有普通数据类型和String类型是深拷贝!

2、二维数组(浅拷贝)

//二维数组

public static void twoArray() {

int[] arr1 = {1, 2};

int[] arr2 = {3, 4};

int[] arr3 = {5, 6};

int[][] src = new int[][]{arr1, arr2, arr3};

print(“原始模样:”, src);

int[][] dest = new int[3][];

System.arraycopy(src, 0, dest, 0, 3);

System.out.println(“改变前”);

print("src = ", src);

print("dest = ", dest);

//原数组改变后观察新数组是否改变,改变->浅复制,不改变->深复制

src[0][0] = -1;

System.out.println(“改变后”);

print("src = ", src);

print("dest = ", dest);

}

//二维数组toString()

private static void print(String string, int[][] arr) {

System.out.print(string);

for (int[] a : arr) {

for (int i : a) {

System.out.print(i + " ");

}

System.out.print(“,”);

}

System.out.println();

}

二维数组属于浅拷贝,原始数组改变后,复制的数据也发生了改变!

3、对象复制(深拷贝?)

四、System.arraycopy是不安全的


1、代码实例

多线程对数组进行复制,看System.arraycopy线程是否安全?

package com.guor.test.javaSE.collection;

import java.util.Arrays;

import java.util.concurrent.locks.Condition;

import java.util.concurrent.locks.ReentrantLock;

public class ArrayTest2 {

private static int[] arrayOriginal = new int[1024 * 1024 * 10];

private static int[] arraySrc = new int[1024 * 1024 * 10];

private static int[] arrayDest = new int[1024 * 1024 * 10];

private static ReentrantLock lock = new ReentrantLock();

private static void modify() {

for (int i = 0; i < arraySrc.length; i++) {

arraySrc[i] = i + 1;

}

}

private static void copy() {

System.arraycopy(arraySrc, 0, arrayDest, 0, arraySrc.length);

}

private static void init() {

for (int i = 0; i < arraySrc.length; i++) {

arrayOriginal[i] = i;

arraySrc[i] = i;

arrayDest[i] = 0;

}

}

private static void doThreadSafeCheck() throws Exception {

for (int i = 0; i < 100; i++) {

System.out.println("run count: " + (i + 1));

init();

Condition condition = lock.newCondition();

new Thread(new Runnable() {

@Override

public void run() {

lock.lock();

condition.signalAll();

lock.unlock();

copy();

}

}).start();

lock.lock();

// 这里使用 Condition 来保证拷贝线程先已经运行了.

condition.await();

lock.unlock();

Thread.sleep(2); // 休眠2毫秒, 确保拷贝操作已经执行了, 才执行修改操作.

modify();

// 如果 System.arraycopy 是线程安全的, 那么先执行拷贝操作, 再执行修改操作时, 不会影响复制结果, 因此 arrayOriginal 必然等于 arrayDist;

if (!Arrays.equals(arrayOriginal, arrayDest)) {

throw new RuntimeException(“System.arraycopy is not thread safe”);

}

}

}

public static void main(String[] args) throws Exception {

//doThreadSafeCheck();

executeTime();

}

private static void executeTime() {

String[] srcArray = new String[1000000];

String[] forArray = new String[srcArray.length];

String[] arrayCopyArray = new String[srcArray.length];

//初始化数组

for(int i = 0 ; i < srcArray.length ; i ++){

srcArray[i] = String.valueOf(i);

}

long forStartTime = System.currentTimeMillis();

for(int index = 0 ; index < srcArray.length ; index ++){

forArray[index] = srcArray[index];

}

long forEndTime = System.currentTimeMillis();

System.out.println(“for方式复制数组:” + (forEndTime - forStartTime));

long arrayCopyStartTime = System.currentTimeMillis();

System.arraycopy(srcArray,0,arrayCopyArray,0,srcArray.length);

long arrayCopyEndTime = System.currentTimeMillis();

System.out.println(“System.arraycopy复制数组:” + (arrayCopyEndTime - arrayCopyStartTime));

}

}

2、代码思路分析

  1. arrayOriginal 和 arraySrc 初始化时是相同的, 而 arrayDist 是全为零的.

  2. 启动一个线程运行 copy() 方法来拷贝 arraySrc 到 arrayDist 中.

  3. 在主线程执行 modify() 操作, 修改 arraySrc 的内容. 为了确保 copy() 操作先于 modify() 操作, 我使用 Condition, 并且延时了两毫秒, 以此来保证执行拷贝操作(即System.arraycopy) 先于修改操作.

  4. 根据第三点, 如果 System.arraycopy 是线程安全的, 那么先执行拷贝操作, 再执行修改操作时, 不会影响复制结果, 因此 arrayOriginal 必然等于 arrayDist; 而如果 System.arraycopy 是线程不安全的, 那么 arrayOriginal 不等于 arrayDist.

3、控制台输出

往期精彩内容:

Java知识体系总结(2021版)

超详细的springBoot学习笔记

Java多线程基础知识总结(绝对经典)

Java面试题总结(附答案)

Vue基础知识总结(绝对经典)

常见数据结构与算法整理总结

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

针对最近很多人都在面试,我这边也整理了相当多的面试专题资料,也有其他大厂的面经。希望可以帮助到大家。

最新整理面试题
在这里插入图片描述

上述的面试题答案都整理成文档笔记。也还整理了一些面试资料&最新2021收集的一些大厂的面试真题

最新整理电子书

在这里插入图片描述

最新整理大厂面试文档

在这里插入图片描述

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
针对最近很多人都在面试,我这边也整理了相当多的面试专题资料,也有其他大厂的面经。希望可以帮助到大家。

最新整理面试题
[外链图片转存中…(img-5hOnGmwr-1713451725504)]

上述的面试题答案都整理成文档笔记。也还整理了一些面试资料&最新2021收集的一些大厂的面试真题

最新整理电子书

[外链图片转存中…(img-09rzAnSW-1713451725506)]

最新整理大厂面试文档

[外链图片转存中…(img-LMokP54j-1713451725508)]

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 16
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值