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必须是静态的,就算是实例方法,每个对象都有这个方法,但操作的类变量是共享的呀,求解释?
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必须是静态的,就算是实例方法,每个对象都有这个方法,但操作的类变量是共享的呀,求解释?
解决方案 »
- 来看这三道题,来理解“聚合和耦合”的关系!
- 【三种青年】之判断字符串内容是否为空
- 判断长整型数是2的倍数
- 关于一维数组开头插入单元的问题
- RTFEditorKit读中文rtf文件失败
- java网络编程的异常?急!在线等,高手们帮帮忙啊。
- 求张孝祥JAVA视频教学 高级篇 下载地址 给个下载地址就结帖
- 急问! 帮我看看为什么没有输出,很短的代码
- 各位高手,junit,ant,structs问题
- 在一个文件中的多个类之间访问权限的定义问题。
- 高手们呀!!为什么process的waitFor不等呀!!!
- JAVA人机猜拳中遇到Exception in thread "main" java.lang.NullPointerException
如果不是同步的问题,那么是不是静态均可。因为它不需要访问non-static变量这个方法被定义为同步的,目的就是两个线程不会同时操作那个filesCompressed++。现在static synchronized,任何GZipThread实例都会被同步。如果变成non-static synchronized,那么这个同步,只对当前对象有效。不同实例间不会互锁。起不到同步的作用。
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)这个方法不是静态的,不也同步了吗?结合这个代码您再解释下,谢谢
if(!files[j].isDirectory()){//不递归处理目录
totalFiles++;
synchronized(pool){
pool.add(0, files[j]);
pool.notifyAll();
}
里面的i是j,写错了