java線程安全的list
1. java實際開發中set,Map,List分別用在什麼情況
set、map、list是Java API封裝的數據結構。之所以封裝它們,是為了符合數學意義上的set、map和list上的一些特唯賣點。
比如set(集合)具有無序性,而且元素不能重復。
map主要是散列思想,即key-value值對。
list是鏈表結構,插入和刪除元素,一個在頭,一個在尾。
另外還有Stack是同一端插入和刪除。
你說他們功能一樣其實是錯的,雖然對於某些問題用他們都可以解決,比如迷宮問題,可以用Stack,可以用鏈表,甚至可以直接用個簡單的一維數組(因為多維數組可以由一維數組表示),但是解決時的復雜度是不同的。這其中除了演算法中的時間、空腔老間代價的不同(比如使用散列,搜索時間大大減少,但是佔用空間增大),當然還包括使用不同數據結構解決不同問題時的「自然」程度(即讓別人容易明白你的演算法的程度)。
說了這么多,其實封裝這些東西就是為了方便編程,方便實現功能。
就像你可以說:「一條語句和一個函數(語句組成)本質上都是相同的,那為什麼要那麼麻煩設計函數?」那你就可以去查查函數編程思想和之後發展起來的面向對象指圓逗編程思想的優勢。
最後再提下Java裡面一些高級點的東西,即所謂線程安全,某些數據結構封裝類不是線程安全的,而另外一些是,這些你可以去查看API或者底層代碼實現,要花費很大耐心的
2. 怎樣保證線程安全
如何確保Java線程安全?
java中,線程安全的解決方法或過程:
1.如果對象是immutable,則是線程安全的,例如:String,可以放心使用。
2. 如果對象是線程安全的,則放心使用。
3.有條件線程安全,對於Vector和Hashtable一般情況下是線程安全的,但是對於某些特殊情況,需要通過額外的synchronized保證線程安全。
4.使用synchronized關鍵字。
什麼是線程安全,實現線程肆中備安全有哪些方法
自己學習的時候做了一些筆記,希望對你有幫助
當一個類已經很好的同步以保護它的數據時,這個類就稱為「線程安全的」---我沒有跑題...
5.線程的同步與死鎖
1.什麼是同步
通過synchronized關鍵字標識方法或者代碼塊,限制線程對其內容的操作(同步詳細介紹參見 .)
2.為什麼要同步
java允許多線程並發控制,當多個線程同時操作一個可共享的資源變數時(如數據的增刪改查),
將會導致數據不準確,相互之間產生沖突,因此加入同步鎖以避免在該線程沒有完成操作之前,被其他線程的調用,
從而保證了該變數的唯一性和准確性.
3.進行同步的格式
同步代碼塊
synchronized (同步的線程對象){
需要同步的代碼塊;
}
同步方法
synchronized 其他訪問修培攔飾符返回值方法名稱(){
方法內容
}
(synchronized也可以修飾靜態方法,此時如果調用該靜態方法,將會鎖住整個類)
4.什麼是死鎖
死鎖是進程死鎖的簡稱,是指多個進程循環等待它方佔有的資源而無限期地僵持下去的局面。它是計算機操作系統乃至並發程序設計中最難處理的問題之一
死鎖的解決
(死鎖詳細介紹參見進程死鎖及解決辦法.docx)
5.注意點
1.同步是一種高開銷的操作,因此應該盡量減少同步的內容。
通常沒有必要同步整個方法,使用synchronized代碼塊同步關鍵代碼即可。
怎樣保證線程安全,程序運行
只需要兩個線程和一個數據緩存鏈。 線程1:圖片採集線程,不停的採集數據,放到數據鏈里緩存
php如何保證線程安全
線程安全本身在php 的運行原理上就做到了,每個請求重新分配的內存空間,所謂php 的現線程安全,指的是 php擴展, 隨著擴展模塊的啟動,分配的內存可以提供給多個請求調用.
php線程安全通過全局的global_id ,為每個全局變數做了唯一ID的區分.
java中 sevlert 如何線程安全如何保證?
首先先說BS是什麼:
BS 指的是網站開發建設,程序員從無到有創建出一個程序,網站,或游戲,通常稱之為開發。
JAVA中BS開發:
指的是用java進行網站開發。
通常,單位在招人時,都希望是招熟手,也就是所謂的有開發經驗的程序員。
java中所謂的BS開發經驗:
指的就是java開發程序員,有開發過網站項目的經驗。
關於BS網站開發要求:
別的語言我不知道,但是java我還能說上一說,因為我本身就是這個行業的從業者。
首先,要會基礎的HTML/CSS,起碼你要看的懂做樣式的同事給你的東西。
然後,Servlet,JSP,javaScript,這些要學好,當然,重中之重是java基礎扎實,不然,你讀不懂別人的邏輯,也無法按照單位給的需求實現出功能。
最後,就是對框架的運用熟練了,每個單位用的框架不同,我用的SpringMVC框架。
請教多線程資料庫程序如何保證線程安全
你的提問就有問題
當你的程序不管是不是多線程的
獲得到一個資料庫連接是 資料庫會把這個連接標記為繁忙 當其他程序訪問時它會返回另外空閑的連接
連接個數是有限的 如果一直不釋放連接 資料庫就會告訴你連接已經使用完了
這里和線程安全有何關系呢? 線程安全和資料庫操作沒有直接關系
除了synchronized和lock還有哪些保證線程安全的方法
1 每次查詢少查點,用rowid記錄標記位,下次查詢從標記位開始。就是個變裂毀相的分頁。
2 jdk1.5以後有了java.util.concurrent包。
wait/notify 是另外一種方式?我第一次聽說。
spring singleton實例中的變數怎麼保證線程安全
spring中管理的bean實例默認情況下是單例的[sigleton類型],就還有prototype類型
按其作用域來講有sigleton,prototype,request,session,global session。
spring中的單例與設計模式裡面的單例略有不同,設計模式的單例是在整個應用中只有一個實例,而spring中的單例是在一個IoC容器中就只有一個實例。
但spring中的單例也不會影響應用的並發訪問,【不會出現各個線程之間的等待問題,或是死鎖問題】因為大多數時候客戶端都在訪問我們應用中的業務對象,而這些業務對象並
沒有做線程的並發限制,只是在這個時候我們不應該在業務對象中設置那些容易造成出錯的成員變數,在並發訪問時候這些成員變數將會是並發線程中的共享對象,那麼這個時候
就會出現意外情況。
那麼我們的Eic-server的所有的業務對象中的成員變數如,在Dao中的xxxDao,或controller中的xxxService,都會被多個線程共享,那麼這些對象不會出現同步問題嗎,比如會造
成資料庫的插入,更新異常?
還有我們的實體bean,從客戶端傳遞到後台的controller-->service-->Dao,這一個流程中,他們這些對象都是單例的,那麼這些單例的對象在處理我們的傳遞到後台的實體bean不
會出問題嗎?
答:[實體bean不是單例的],並沒有交給spring來管理,每次我們都手動的New出來的【如EMakeType et = new EMakeType();】,所以即使是那些處理我們提交數據的業務處理類
是被多線程共享的,但是他們處理的數據並不是共享的,數據時每一個線程都有自己的一份,所以在數據這個方面是不會出現線程同步方面的問題的。但是那些的在Dao中的
xxxDao,或controller中的xxxService,這些對象都是單例那麼就會出現線程同步的問題。但是話又說回來了,這些對象雖然會被多個進程並發訪問,可我們訪問的是他們裡面的方
法,這些類裡面通常不會含有成員變數,那個Dao裡面的ibatisDao是框架裡面封裝好的,已經被測試,不會出現線程同步問題了。所以出問題的地方就是我們自己系統裡面的業務
對象,所以我們一定要注意這些業務對象裡面千萬不能要獨立成員變數,否則會出錯。
所以我們在應用中的業務對象如下例子;
controller中的成員變數List和paperService:
public class TestPaperController extends BaseController {
private static final int List = 0;
@Autowired
@Qualifier("papersService")
private TestPaperService papersService ;
public Page queryPaper(int pageSize, int page,TestPaper paper) throws EicException{
RowSelection localRowSelection = getRowSelection(pageSize, page);
List paperList = papersService.queryPaper(paper,localRowSelecti......>>
如何解決線程安全問題
有2種解決方法。
第一,是採用原子變數,畢竟線程安全問題最根本上是由於全局變數和靜態變數引起的,只要保證了對於變數的寫操作要麼全寫要麼不寫,就可以解決線程安全,定義變數用sig_atomic_t和volatile。
第二,就是實現線程間同步啦,用互斥索,信號量。讓線程有序的訪問變數就可以啦
spring mvc怎麼保證線程安全
參考如下內容,講的很好,可以配置controller為單例模式,每次都新建一個:
SpringMVC和Struts2中是並發訪問否會存在線程安全問題。
對於使用過SpringMVC和Struts2的人來說,大家都知道SpringMVC是基於方法的攔截,而Struts2是基於類的攔截。
對於Struts2來說,因為每次處理一個請求,struts就會實例化一個對象;這樣就不會有線程安全的問題了;
而Spring的controller默認是Singleton的,這意味著每一個request過來,系統都會用原有的instance去處理,這樣導致兩個結果:
一是我們不用每次創建Controller,二是減少了對象創建和垃圾收集的時間;由於只有一個Controller的instance,當多個線程調用它的時候,它裡面的instance變數就不是線程安全的了,會發生竄數據的問題。
當然大多數情況下,我們根本不需要考慮線程安全的問題,比如,service等,除非在bean中聲明了實例變數。因此,我們在使用spring mvc 的contrller時,應避免在controller中定義實例變數。
如:
[java] view plain print?
public class Controller extends AbstractmandController {
protected pany pany;
protected ModelAndView handle(HttpServletRequest request,HttpServletResponse response,Object mand,BindException errors) throws Exception {
pany = ................;
}
}
解決方案:
有幾種解決方法:
1、在Controller中使用ThreadLocal變數
2、在spring配置文件Controller中聲明 scope="prototype",每次都創建新的controller
所在在使用spring開發web 時要注意,默認Controller、Dao、Service都是單例的。
3. java里線程安全是什麼意思有什麼作用
比如說,兩個線程操作同一個ArrayList變數,那麼一個線程這一時刻讀的數據可能在下一刻要改變。
一般在類似於下面的情景下考慮線程安全的問題:
ArrayList procts=new ArrayList ();
procts用來存放生產出來的產品。
現在假設:有3個消費者線程,2個生產者線程。
每個生產者線程生產出一個產品,執行
procts.add(new Proct());
每個消費者線程消費一個產品執行
if(procts.size()>=1){ procts.remove(0);}
如果procts里現在只有一個產品可以消費,但是有2個消費者線程請求消費,那麼就有可能出現一個產品被同時消費的問題,而這是和實際不符的。
但是不同的線程訪問Vector的時候不會發生這種錯誤,因為java會有相應的機制是同一時刻只有一個線程對這個變數操作。
這就是所謂的:
Vector:是線程安全的
ArrayList:不是線程安全的
4. 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的集合工具類在添加方面更加快一些,其他方法這里篇幅關系就不測試了,大家有興趣去試一下。