代码有一处不懂,求解释

yanxing2012 2013-03-02 10:33:15
import java.io.*;
import java.util.*;
import java.util.zip.*;

public class GZipThread extends Thread {
private List pool;
private static int filesCompressed = 0;

public GZipThread(List pool) {
this.pool = pool;
}

private static synchronized void incrementFilesCompressed() {
// 所有线程同步同一个class对象,操作同一个静态filesCompressed
filesCompressed++;
}

public void run() {
while (filesCompressed != GZipAllFiles.getNumberOfFilesToBeCompressed()) {
File input = null;
synchronized (pool) {
while (pool.isEmpty()) {
if (filesCompressed == GZipAllFiles
.getNumberOfFilesToBeCompressed()) {
System.out.println("Thread ending");
return;
}
try {
pool.wait();//得到通知,获得所等待的锁就执行wait()后面的语句
} catch (InterruptedException ex) {
}
}//while (pool.isEmpty())循环结束
input = (File) pool.remove(pool.size() - 1);
incrementFilesCompressed();
}//synchronized (pool)同步结束
if (!input.getName().endsWith(".gz")) {// 不压缩已经压缩过的文件
try {
InputStream in = new FileInputStream(input);
in = new BufferedInputStream(in);
File output = new File(input.getParent(), input.getName()
+ ".gz");
if (!output.exists()) {// 不覆盖已经存在的文件
OutputStream out = new FileOutputStream(output);
out = new GZIPOutputStream(out);
out = new BufferedOutputStream(out);
int b;
while ((b = in.read()) != -1)
out.write(b);
out.flush();
out.close();
in.close();
}
} catch (IOException ex) {
System.err.println(ex);
}
}
}//最外层while结束
}//run()结束
}


import java.io.*;
import java.util.*;

public class GZipAllFiles {

public final static int THREAD_COUNT = 4;
public static int filesToBeCompressed = -1;

public static void main(String[] args) {
Vector pool=new Vector();
GZipThread[] threads=new GZipThread[THREAD_COUNT];
for(int i=0;i<threads.length;i++){
threads[i]=new GZipThread(pool);
threads[i].start();
}
int totalFiles=0;
for(int i=0;i<args.length;i++){
File f=new File(args[i]);
if(f.exists()){
if(f.isDirectory()){//文件是一个目录时****
File[] files=f.listFiles();
for(int j=0;j<files.length;i++){
if(!files[j].isDirectory()){//不递归处理目录
totalFiles++;
synchronized(pool){
pool.add(0, files[j]);
pool.notifyAll();
}
}
}//内层for结束
}//****处for结束
else{
totalFiles++;
synchronized(pool){
pool.add(0,f);
pool.notifyAll();
}
}//else结束
}
}//最外层for结束
filesToBeCompressed=totalFiles;
for(int i=0;i<threads.length;i++){//没有文件再添加到池中,中断等待的线程
threads[i].interrupt();
}
}

public static int getNumberOfFilesToBeCompressed() {
return filesToBeCompressed;
}

}


书上说incrementFilesCompressed()方法必须是同步静态方法,不能是同步实例方法,filesCompressed是静态的了,为何incrementFilesCompressed必须是静态的,就算是实例方法,每个对象都有这个方法,但操作的类变量是共享的呀,求解释?
...全文
445 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
yanxing2012 2013-03-09
  • 打赏
  • 举报
回复
引用 3 楼 shine333 的回复:
因为Frame这个,只有一个实例在处理
这不只一个实例吧,最上面的代码,那个方法我去掉static,代码也没有运行错误
yanxing2012 2013-03-09
  • 打赏
  • 举报
回复
引用 1 楼 shine333 的回复:
你是说这个方法为何是静态的? 如果不是同步的问题,那么是不是静态均可。因为它不需要访问non-static变量 这个方法被定义为同步的,目的就是两个线程不会同时操作那个filesCompressed++。 现在static synchronized,任何GZipThread实例都会被同步。如果变成non-static synchronized,那么这个同步,……
这几天看了不同的资料,你说的还是对的,static去掉后,无法锁定共享资源,不能锁定GZipThread类的所有实类。至于去掉static后,测试结果没有错误,应该是测试文件太少的原因。。。
yanxing2012 2013-03-09
  • 打赏
  • 举报
回复
引用 3 楼 shine333 的回复:
因为Frame这个,只有一个实例在处理
看错了,是只有一个实例运行,但我问的最上面的代码,有四个实例,我认为你说的对,没有static,无法实现对所有线程同步同一个class对象,可是我想不通的是:那个方法去掉static,测试了一下,没有问题,想不通。。。另外
for(int j=0;j<files.length;i++){
                        if(!files[j].isDirectory()){//不递归处理目录
                            totalFiles++;
                            synchronized(pool){
                                pool.add(0, files[j]);
                                pool.notifyAll();
                        }
里面的i是j,写错了
shine333 2013-03-08
  • 打赏
  • 举报
回复
当然,我没看全,说的只是“感觉
shine333 2013-03-08
  • 打赏
  • 举报
回复
因为Frame这个,只有一个实例在处理
yanxing2012 2013-03-03
  • 打赏
  • 举报
回复
引用 1 楼 shine333 的回复:
你是说这个方法为何是静态的? 如果不是同步的问题,那么是不是静态均可。因为它不需要访问non-static变量 这个方法被定义为同步的,目的就是两个线程不会同时操作那个filesCompressed++。 现在static synchronized,任何GZipThread实例都会被同步。如果变成non-static synchronized,那么这个同步,……
import java.awt.*;
    import java.awt.event.*;
public class Jpro13_5 extends Frame{
		protected static final String[] NAMES = {"A","B"};
		private int accounts[] = {1000,1000};
		private TextArea info = new TextArea(5,40);
		private TextArea status = new TextArea(5,40);
		public Jpro13_5 (){
			super("Jpro13_5");
			setLayout(new GridLayout(2,1));
			add(makePanel(info,"Accounts"));
			add(makePanel(status,"Threads"));
			validate();pack();setVisible(true);
			Jpro13_5Thread A = new  Jpro13_5Thread(0,this,status);
			Jpro13_5Thread B = new  Jpro13_5Thread(1,this,status);
			addWindowListener(new WindowAdapter(){
				public void windowClosing(WindowEvent we){
					System.exit(0);
				}
			});
		}
		public synchronized void transfer(int from,int into,int amount){
			info.append("\nAccount A: $" + accounts[0]);
			info.append("\tAccount B: $" + accounts[1]);
info.append("\n=> $" + amount + " from " + NAMES[from] + " to " + NAMES[into]);
			while(accounts[from] < amount){
				try{
					wait();
				}catch(InterruptedException ie){
					System.err.println("Error: " + ie);
				}
			}
			accounts[from] -= amount;
			accounts[into] +=amount;
notify();
		}
		private Panel makePanel(TextArea text,String title){
			Panel p = new Panel();
			p.setLayout(new BorderLayout());
			p.add("North",new Label(title));p.add("Center",text);
			return p;
		}
		public static void main(String args[]){
			Jpro13_5 bank = new Jpro13_5();
		}
	}
	class Jpro13_5Thread extends Thread{
		private Jpro13_5 bank;
		private int id;
		private TextArea display;
		public Jpro13_5Thread(int _id,Jpro13_5 _bank,TextArea _display){
			bank = _bank;
			id = _id;
			display = _display;
			start();
		}
		public void run(){
			while(true){
				int amount = (int)(900*Math.random());
display.append("\nThread " + Jpro13_5.NAMES[id] + " sends $ " + amount + " into " + Jpro13_5.NAMES[(1-id)]);
					try{
						sleep(50);
					}catch(InterruptedException ie){
						System.err.println("Interrupted");
					}
					bank.transfer(id,1-id,amount);
				}
			}
		}
那public synchronized void transfer(int from,int into,int amount)这个方法不是静态的,不也同步了吗?结合这个代码您再解释下,谢谢
shine333 2013-03-02
  • 打赏
  • 举报
回复
你是说这个方法为何是静态的? 如果不是同步的问题,那么是不是静态均可。因为它不需要访问non-static变量 这个方法被定义为同步的,目的就是两个线程不会同时操作那个filesCompressed++。 现在static synchronized,任何GZipThread实例都会被同步。如果变成non-static synchronized,那么这个同步,只对当前对象有效。不同实例间不会互锁。起不到同步的作用。

62,621

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧