当前位置:首页 » 编程语言 » java线程list

java线程list

发布时间: 2022-12-23 05:27:38

A. java list是不是线程安全的

直接用Vector就可以了,它是线程安全的。ArrayList list=new ArrayList();就需要锁了,涉及同步,可以参考网上买票例子做。

B. Java 多线程处理一个List

多线程并发操作,
请使用Collections.synchronizedList(new
LinkedList
());
这样就是线程安全
另外LinkedList插入快
再次就是启动jvm的参数设置
-Xms512m
Xmx1024m

C. java中List是线程同步的吗

List本身是一个接口,有一个类叫Vector,它实现了List,并且这个Vector是线程同步的。 在实际运用中,至少我没看见谁直接用List来装东西,最多会是这样:

List list = new ArrayList();

List list = new Vector();

D. java 定义一个线程池 循环遍历list,进行读写操作

importjava.util.List;
importjava.util.concurrent.Callable;
importjava.util.concurrent.ExecutionException;
importjava.util.concurrent.ExecutorService;
importjava.util.concurrent.Executors;
importjava.util.concurrent.Future;

/**
*并发处理器
*适用于如下场景(举例):
*一个任务队列,有150个任务需要并发处理,使用此对象,可以每次并发执行20次(可设置),则总共串行执行8次并发,可获取执行结果
*
*@param<T>类型T限制为任务Callable使用的数据对象和返回结果的数据对象为同一个bean
*/
publicclassConcurrentExcutor<T>
{
/**非空,所有任务数组*/
privateCallable<T>[]tasks;

/**非空,每次并发需要处理的任务数*/
privateintnumb;

/**可选,存放返回结果,这里有个限制,泛型T必须为Callable返回的类型T*/
privateList<T>result;

/**
*无参构造
*/
publicConcurrentExcutor()
{
super();
}

/**
*不需要返回结果的任务用此创建对象
*@paramtasks
*@paramnumb
*/
publicConcurrentExcutor(Callable<T>[]tasks,intnumb)
{
super();
this.tasks=tasks;
this.numb=numb;
}

/**
*需要结果集用此方法创建对象
*@paramtasks
*@paramnumb
*@paramresult
*/
publicConcurrentExcutor(Callable<T>[]tasks,intnumb,List<T>result)
{
super();
this.tasks=tasks;
this.numb=numb;
this.result=result;
}

publicvoidexcute()
{
//参数校验
if(tasks==null||numb<1)
{
return;
}

//待处理的任务数
intnum=tasks.length;
if(num==0)
{
return;
}

//第一层循环,每numb条数据作为一次并发
for(inti=0;i<(int)Math.floor(num/numb)+1;i++)
{
//用于记录此次numb条任务的处理结果
Future[]futureArray;
if(numb>num)
{
futureArray=newFuture[num];
}
else
{
futureArray=newFuture[numb];
}

//创建线程容器
ExecutorServicees=Executors.newCachedThreadPool();

//第二层循环,针对这numb条数据进行处理
for(intj=i*numb;j<(i+1)*numb;j++)
{
//如果超出数组长度,退出循环
if(j+1>num)
{
break;
}
//执行任务,并设置Future到数组中
futureArray[j%numb]=es.submit(tasks[j]);
}

//将结果放入result中
if(result!=null)
{
for(intj=0;j<futureArray.length;j++)
{
try
{
if(futureArray[j]!=null)
{
Objecto=futureArray[j].get();
result.add((T)o);
}
}
catch(InterruptedExceptione)
{
System.out.println("处理Future时发生InterruptedException异常,目标Future为:"+futureArray[j].toString());
e.printStackTrace();
}
catch(ExecutionExceptione)
{
System.out.println("处理Future时发生ExecutionException异常,目标Future为:"+futureArray[j].toString());
e.printStackTrace();
}
}
}

es.shutdown();
}
}

E. Java的List如何实现线程安全

Java的List如何实现线程安全?

Collections.synchronizedList(names);效率最高,线程安全

Java的List是我们平时很常用的集合,线程安全对于高并发的场景也十分的重要,那么List如何才能实现线程安全呢 ?


加锁

首先大家会想到用Vector,这里我们就不讨论了,首先讨论的是加锁,例如下面的代码


public class Synchronized{

private List<String> names = new LinkedList<>();

public synchronized void addName(String name ){
names.add("abc");
}
public String getName(Integer index){
Lock lock =new ReentrantLock();
lock.lock();
try {
return names.get(index);
}catch (Exception e){
e.printStackTrace();
}
finally {
lock.unlock();
}
return null;
}
}

synchronized一加,或者使用lock 可以实现线程安全,但是这样的List要是很多个,代码量会大大增加。

java自带类

在java中我找到自带有两种方法


CopyOnWriteArrayList

CopyOnWrite 写入时复制,它使一个List同步的替代品,通常情况下提供了更好的并发性,并且避免了再迭代时候对容器的加锁和复制。通常更适合用于迭代,在多插入的情况下由于多次的复制性能会一定的下降。


下面是add方法的源代码


public boolean add(E e) {
final ReentrantLock lock = this.lock; // 加锁 只允许获得锁的线程访问
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
// 创建个长度加1的数组并复制过去
Object[] newElements = Arrays.Of(elements, len + 1);
newElements[len] = e; // 赋值
setArray(newElements); // 设置内部的数组
return true;
} finally {
lock.unlock();
}
}


Collections.synchronizedList

Collections中有许多这个系列的方法例如


主要是利用了装饰者模式对传入的集合进行调用 Collotions中有内部类SynchronizedList


static class SynchronizedList<E>
extends SynchronizedCollection<E>
implements List<E> {
private static final long serialVersionUID = -7754090372962971524L;

final List<E> list;

SynchronizedList(List<E> list) {
super(list);
this.list = list;
}
public E get(int index) {
synchronized (mutex) {return list.get(index);}
}
public E set(int index, E element) {
synchronized (mutex) {return list.set(index, element);}
}
public void add(int index, E element) {
synchronized (mutex) {list.add(index, element);}
}
public E remove(int index) {
synchronized (mutex) {return list.remove(index);}
}

static class SynchronizedCollection<E> implements Collection<E>, Serializable {
private static final long serialVersionUID = 3053995032091335093L;

final Collection<E> c; // Backing Collection
final Object mutex; // Object on which to synchronize


这里上面的mutex就是锁的对象 在构建时候可以指定锁的对象 主要使用synchronize关键字实现线程安全

/**
* @serial include
*/
static class SynchronizedList<E>
extends SynchronizedCollection<E>
implements List<E> {
private static final long serialVersionUID = -7754090372962971524L;

final List<E> list;

SynchronizedList(List<E> list) {
super(list);
this.list = list;
}
SynchronizedList(List<E> list, Object mutex) {
super(list, mutex);
this.list = list;
}
这里只是列举SynchronizedList ,其他类类似,可以看下源码了解下。

测试
public class Main {
public static void main(String[] args) {
List<String> names = new LinkedList<>();
names.add("sub");
names.add("jobs");
// 同步方法1 内部使用lock
long a = System.currentTimeMillis();
List<String> strings = new CopyOnWriteArrayList<>(names);
for (int i = 0; i < 100000; i++) {
strings.add("param1");
}
long b = System.currentTimeMillis();
// 同步方法2 装饰器模式使用 synchronized
List<String> synchronizedList = Collections.synchronizedList(names);
for (int i = 0; i < 100000; i++) {
synchronizedList.add("param2");
}
long c = System.currentTimeMillis();
System.out.println("CopyOnWriteArrayList time == "+(b-a));
System.out.println("Collections.synchronizedList time == "+(c-b));
}
}


两者内部使用的方法都不一样,CopyOnWriteArrayList内部是使用lock进行加锁解锁完成单线程访问,synchronizedList使用的是synchronize

进行了100000次添加后时间对比如下:

可以看出来还是使用了synchronize的集合工具类在添加方面更加快一些,其他方法这里篇幅关系就不测试了,大家有兴趣去试一下。

F. Java 多线程处理一个List

importjava.util.ArrayList;
importjava.util.List;
importorg.apache.commons.lang3.ArrayUtils;

publicclassTest_4{
/**
*多线程处理list
*
*@paramdata数据list
*@paramthreadNum线程数
*/
(List<String>data,intthreadNum){
intlength=data.size();
inttl=length%threadNum==0?length/threadNum:(length
/threadNum+1);

for(inti=0;i<threadNum;i++){
intend=(i+1)*tl;
HandleThreadthread=newHandleThread("线程["+(i+1)+"]",data,i*tl,end>length?length:end);
thread.start();
}
}

{
privateStringthreadName;
privateList<String>data;
privateintstart;
privateintend;

publicHandleThread(StringthreadName,List<String>data,intstart,intend){
this.threadName=threadName;
this.data=data;
this.start=start;
this.end=end;
}

publicvoidrun(){
//TODO这里处理数据
data.subList(start,end).add("^&*");
System.out.println(threadName)
}

}

publicstaticvoidmain(String[]args){
Test_4test=newTest_4();
//准备数据
List<String>data=newArrayList<String>();
for(inti=0;i<5000;i++){
data.add("item"+i);
}
test.handleList(data,5);
System.out.println(ArrayUtils.toString(data));
}
}

G. java list是不是线程安全的

是线程安全的,但是hashtable是全部加锁的。
现在有更好的concurrenthashmap
这个是锁node的。当你读取key为某个值得时候
这个key下的value是被锁的,但是其他的node不会被影响。

H. java中List是线程同步的吗

List本身是一个接口,有一个类叫Vector,它实现了List,并且这个Vector是线程同步的。
在实际运用中,至少我没看见谁直接用List来装东西,最多会是这样:
List
list
=
new
ArrayList();
List
list
=
new
Vector();

I. Java的List如何实现线程安全

解决这个问题通常有两种方法(个人认为)
一:使用synchronized关键字,这个大家应该都很熟悉了,不解释了;
二:使用Collections.synchronizedList();使用方法如下:
假如你创建的代码如下:List<Map<String,Object>> data=new ArrayList<Map<String,Object>>();
那么为了解决这个线程安全问题你可以这么使用Collections.synchronizedList(),如:
List<Map<String,Object>> data=Collections.synchronizedList(new ArrayList<Map<String,Object>>());
其他的都没变,使用的方法也几乎与ArrayList一样,大家可以参考下api文档;
额外说下 ArrayList与LinkedList;这两个都是接口List下的一个实现,用法都一样,但用的场所的有点不同,ArrayList适合于进行大量的随机访问的情况下使用,LinkedList适合在表中进行插入、删除时使用,二者都是非线程安全,解决方法同上(为了避免线程安全,以上采取的方法,特别是第二种,其实是非常损耗性能的)。

热点内容
网吧u盘拒绝访问 发布:2025-05-16 14:13:50 浏览:260
无线网检查网络配置是怎么回事 发布:2025-05-16 14:04:03 浏览:220
网络爬虫python代码 发布:2025-05-16 14:03:26 浏览:516
汽车小组件怎么弄到安卓桌面 发布:2025-05-16 13:51:12 浏览:220
linuxg编译器下载 发布:2025-05-16 13:50:58 浏览:776
centosc编译器 发布:2025-05-16 13:50:17 浏览:948
安卓手机如何变换桌面 发布:2025-05-16 13:39:33 浏览:515
sql存储过程命令 发布:2025-05-16 13:17:54 浏览:146
用纸做解压小玩具西瓜 发布:2025-05-16 13:04:09 浏览:936
局域网xp无法访问win7 发布:2025-05-16 13:03:58 浏览:943