當前位置:首頁 » 編程語言 » 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適合在表中進行插入、刪除時使用,二者都是非線程安全,解決方法同上(為了避免線程安全,以上採取的方法,特別是第二種,其實是非常損耗性能的)。

熱點內容
超級訪問陳小春應采兒 發布:2025-05-16 09:43:29 瀏覽:477
緩存視頻合並工具最新版 發布:2025-05-16 09:35:03 瀏覽:194
花雨庭伺服器ip地址和埠 發布:2025-05-16 09:34:58 瀏覽:239
同時修改多台伺服器管理地址工具 發布:2025-05-16 09:20:36 瀏覽:421
什麼配置就能玩地平線 發布:2025-05-16 09:13:46 瀏覽:82
python旋轉圖片 發布:2025-05-16 09:13:40 瀏覽:638
少女前線防檢測腳本 發布:2025-05-16 08:59:07 瀏覽:728
編譯器對系統的依賴 發布:2025-05-16 08:37:29 瀏覽:711
javamap數組 發布:2025-05-16 08:37:28 瀏覽:451
移動光貓如何自行修改密碼 發布:2025-05-16 08:20:15 瀏覽:125