java線程問題:當一個目標對象被多個線程共享時候,就是有多個run()方法

當線程被調用之前,系統內存中並沒有為其分配地址.而當run()方法調用該共享線程時,該線程處於被激活態,但是如果沒有start,那麼這個線程還算不上"誕生",而它的結束取決於程序內部的調用機制.當一個線程完成運行時,可處於多個狀態(好久不做JAVA了,有點記不起來了),其中有一個是直接讓其sleep的,也就是消亡.但還有一種消亡狀態就是被回收器自動回收.
以上.
說的不好請糾正.

⑵ java多線程共享變數

兩個線程同來時獲取變數,
獲取之自後.第一個線程++操作,然後進入睡眠.
這時,第二個線程,也獲取到了,做--操作.睡眠.
第一個線程醒來列印的是做過2次運算的數據(++,--)所以是0
第二線程也一樣.
這涉及到多線程安全問題.

⑶ 求一個java數據多線程數據共享的例子,謝謝。

public class ThreadPoolManager {
private static ThreadPoolManager instance = null;
private List<Upload> taskQueue = Collections.synchronizedList(new LinkedList<Upload>());//任務隊列
private WorkThread[] workQueue ; //工作線程(真正執行任務的線程)
private static int worker_num = 6; //工作線程數量(默認工作線程數量是6)
private static int worker_count = 0;

private ThreadPoolManager(){
this(6);
}
private ThreadPoolManager(int num){
worker_num = num;
workQueue = new WorkThread[worker_num];
for(int i=0;i<worker_num;i++){
workQueue[i] = new WorkThread(i);
}
}

public static synchronized ThreadPoolManager getInstance(){
if(instance==null)
instance = new ThreadPoolManager();
return instance;
}

public void addTask(Upload task){
//對任務隊列的操作要上鎖
synchronized (taskQueue) {
if(task!=null){
taskQueue.add(task);
taskQueue.notifyAll();
System.out.println("task id "+task.getInfo() + " submit!");
}

}
}

public void BatchAddTask(Upload[] tasks){
//對任務隊列的修改操作要上鎖
synchronized (taskQueue) {
for(Upload e:tasks){
if(e!=null){
taskQueue.add(e);
taskQueue.notifyAll();
System.out.println("task id "+e.getInfo() + " submit!");
}
}
}
}

public void destory(){
System.out.println("pool begins to destory ...");
for(int i = 0;i<worker_num;i++){
workQueue[i].stopThread();
workQueue[i] = null;
}
//對任務隊列的操作要上鎖
synchronized (taskQueue) {
taskQueue.clear();
}

System.out.println("pool ends to destory ...");
}

private class WorkThread extends Thread{
private int taksId ;
private boolean isRuning = true;
private boolean isWaiting = false;

public WorkThread(int taskId){
this.taksId= taskId;
this.start();
}

public boolean isWaiting(){
return isWaiting;
}
// 如果任務進行中時,不能立刻終止線程,需要等待任務完成之後檢測到isRuning為false的時候,退出run()的方法
public void stopThread(){
isRuning = false;
}

@Override
public void run() {
while(isRuning){
Upload temp = null;
//對任務隊列的操作要上鎖
synchronized (taskQueue) {
//任務隊列為空,等待新的任務加入
while(isRuning&&taskQueue.isEmpty()){
try {
taskQueue.wait(20);
} catch (InterruptedException e) {
System.out.println("InterruptedException occre...");
e.printStackTrace();
}
}
if(isRuning)
temp = taskQueue.remove(0);
}
//當等待新任務加入時候,終止線程(調用stopThread函數)造成 temp = null
if(temp!=null){
System.out.println("task info: "+temp.getInfo()+ " is begining");
isWaiting = false;
temp.uploadPic();
isWaiting = true;
System.out.println("task info: "+temp.getInfo()+ " is finished");
}
}
}
}
}
復制代碼
然後定義任務介面(Task):這里我定義的是上傳圖片的功能介面(這里用抽象類或者介面隨你自己).
Upload
然後定義具體任務類:我這里簡單,讓它睡眠2秒鍾。當然你也可以定義很多實現Upload的任務類。
TaskUpload
測試這個簡單的線程池:
public class ThreadPoolManagerTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Upload[] tasks = createBatchTask(7);
ThreadPoolManager pool = ThreadPoolManager.getInstance();
pool.BatchAddTask(tasks);
pool.destory();
}
private static Upload[] createBatchTask(int n){
Upload[] tasks = new TaskUpload[n];
for(int i = 0;i<n ;i++ ){
tasks[i] = new TaskUpload("我的工作線程 "+ i);
}
return tasks;
}
}

⑷ Java編程多個線程如何訪問同一個共享資源

如果該方法不涉及寫公共的資源比如一個靜態的變數或者寫文件,修改某個資料庫的內值的時候沒有影響容
比如你這個類里的方法只是對輸入的參數做一個計算然後返回計算的值就沒有影響。
但是如果是修改公共的資源比如修改資料庫中存儲的一個value則有可能出現問題,如:

public void writeDb(String key, String value) {
collectiondb();
write(key, value);
closeDbCollection();
}

因為Java的線程運行順序是不一定的,可以第一個線程運行完連接資料庫到後掛起了,這時候第二個線程開始運行,如果你的collectiondb()處理使用的是類中的一個實例變數Connection conn來保存資料庫的連接,當第二個線程運行完畢以後conn也被關閉了,第一個線程繼續執行write函數寫資料庫值的時候就會拋出異常。
這是一個例子,還有其他可能產生臟數據的問題
多線程如果使用公共資源的話最好在方法上聲明synchronized關鍵字讓其同步

⑸ java,ArrayList是在線程間共享的嗎

給你個表格吧
類 速度 多線程安全性 適用方面
Vector 慢 安全 提供了線程序同 步,在多線程是安全的.
ArrayList 快 不安全 多線程不安全
二者各有特點,要看你怎麼取捨.
日常編碼的時候,一般都是單線程程序,採用arraylist較好.
在涉及到網路編程.進程合作的時候,多線程共享變數的時候,採用vector好,舉個例子,資料庫緩沖池採用vector而不是arraylist.

⑹ java中多個線程訪問共享數據的方式有哪些

多個線程對共同數據的訪問的實現,要根據情況而定 (1)當訪問共同的代碼的時候:可以使用同一個Runnable對象,這個Runnable對象中有這個共享數據,比如賣票系統就可以這么做。或者這個共享數據封裝在一個對象當中,然後對這個對象加鎖,也可以實現數據安全訪問。 (2)當各個線程訪問的代碼不同時:這時候要使用不同的Runnable對象,有兩種實現方式: a)將共享數據封裝在另一個對象當中,然後將這個對象逐一的轉遞給各個Runnable對象。操作數據的方法也放進這個對象當中。這樣容易實現各個線程對這個數據的同步和共享。 b)將Runnable對象作為某一個類中的內部類,共享數據作為這個外部類的成員變數,每個線程對共享數據的訪問也交給外部類的方法,比便對共享數據的互斥和通信。Runnable對象調用外部類的操作這個共享數據的方法。 還有一種方式是a)和b)的結合實現,把共享數據封裝到一個對象當中去,這個對象也實現對這個共享數據的操作,這個對象作為外部類的成員變數。然後再創建多個Runnable對象做為內部類,操作這個對象。 總結:對於要是下同步互斥的代碼要放在不同的方法中,並且放在同一個對象當中,容易實現互斥和通信,並且也有利於日後的維護。這樣思路也很清晰。 如有不妥之處,敬請指正。

⑺ 創建一個java程序:兩個或兩個以上的線程需要訪問共享資源

試一試生產消費者問題吧.一個棧空間裝WOTOU然後開啟兩個線程同時消費和生產..滿20次就停止public class Test{
public static void main(String[] args){
SyncStack ss = new SyncStack();
Procer p = new Procer(ss);
Consumer c = new Consumer(ss);
Thread t = new Thread(p);
Thread tt = new Thread(c);
t.start();
tt.start();
}
}class WoTou{
int id;
WoTou(int id){
this.id = id;
}
public String toString(){
return "WoTou" + id;
}
}class SyncStack{ int index = 0;
WoTou[] arrWT = new WoTou[6];
public synchronized void push(WoTou wt){
if(index == arrWT.length){
try{
this.wait();
}catch(InterruptedException e){
e.printStackTrace();
}

}
this.notify();
arrWT[index] = wt;
index ++;

}
public synchronized WoTou pop(){
if(index == 0){
try{
this.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
this.notify();
index --;
return arrWT[index];

}
}class Procer implements Runnable{
SyncStack ss = null;
Procer(SyncStack ss){
this.ss = ss;
}
public void run(){
for(int i = 1;i<20;i++){
WoTou wt = new WoTou(i);
ss.push(wt);
System.out.println("生產了:" + wt);
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
class Consumer implements Runnable{
SyncStack ss = null;
Consumer(SyncStack ss){
this.ss = ss;
}
public void run(){
for(int i = 1;i<20;i++){
WoTou wt = ss.pop();

System.out.println("消費了:" + wt);
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}

⑻ java堆內存被所有線程所共享,不明白2個線程如何共享2個對象中的同名變數。

首先:堆內存共享是相對於棧內存的。棧是每一個線程都獨有的,線程之間互不一向,每一個線程都有自己的棧內存。但是堆內存不一樣,在一個JVM實例裡面,不管你有多少線程,創建了多少對象,都是放在一塊堆內存的。也就是說一個JVM實例棧內存區域是有多個,每一個線程持有一個,而堆內存只有一個,是線程共享的。
其次:針對你這個代碼,這個情況下每一個線程確實是對應著不同的對象。也就是在同一個堆(也只有一個堆)裡面創建了兩個Demo對象。你老師的意思應該是
Demo demo = new demo();
Thread S1=new Thread(demo);
Thread S2=new Thread(demo);
這樣兩個線程都是操作堆內存共享的對象。