java线程共享
⑴ 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);
这样两个线程都是操作堆内存共享的对象。