个人理解并发就是在时间上运行程序(即不同任务在不同时间片上运行),并行就是在空间上运行程序(即不同任务在不同处理器或计算机上运行)。
(1)Thread类通过实现Runnable接口
(2)线程池(ThreadPool)用来管理线程的数量
我们先用一个例子实现:
程序如下
第一版Account
import java.util.concurrent.*;
public class AccountWithoutSync {
private static Account account = new Account();
public static void main(String[] args)
{
ExecutorService executor = Executors.newCachedThreadPool();
for(int i = 0; i < 100; i++)
{
executor.execute(new AddOneYuanTask());
}
executor.shutdown();
while(!executor.isTerminated())
{
}
System.out.println("What is balance? " + account.getBalance());
}
//Inner class
private static class AddOneYuanTask implements Runnable
{
public void run()
{
account.deposit(1);
}
}
private static class Account
{
private int balance = 0;
public int getBalance()
{
return balance;
}
public void deposit(int amount)
{
int newBalance = balance + amount;
//人为地制造延时
try
{
Thread.sleep(5);
}
catch(InterruptedException ex)
{
}
balance = newBalance;
}
}
}
我们运行一下发现balance为4或5,这是个错误的结果,如果一个类的对象在多线程程序中导致竞争状态,则称这个类为线程不安全的。所以这个任务是线程不安全的。
用互斥锁来实现同步,即在一任务开始执行时加锁,执行完毕后释放锁。在释放锁之前其它任务无法执行。同步完全可以避免竞争状态的产生,但有的时候还需要线程之间的相互合作。
然后增加一个向账户提款(Withdraw)的任务,当余额小于取款数时,等待新存入的存款。
Account类添加
privatestaticLocklock=newReentrantLock();//创建一个锁
privatestaticConditionnewDeposit=lock.newCondition();//实现一个条件
Account类中应用互斥锁的的方法如下
withdraw和deposit
然后程序相应的修改修改
第二版Account
public static void main(String[] args)
{
System.out.println("Thread 1 Thread 2 Balance");
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.execute(new DepositTask());
executor.execute(new WithdrawTask());
executor.shutdown();
}
public static class DepositTask implements Runnable
{
public void run()
{
try
{
while(true)
{
account.deposit((int)(Math.random() * 10) + 1);
Thread.sleep(1000);
}
}
catch(InterruptedException ex)
{
ex.printStackTrace();
}
}
}
public static class WithdrawTask implements Runnable
{
public void run()
{
while(true)
{
account.withdraw((int)(Math.random() * 10) + 1);
}
}
}
Java中对socket的使用十分方便,在建立socket连接后就可以使用输入输出流的方法实现数据传输了。
在实现基本的GUI后,在服务器用一个判断条件永远为true的循环来监听客户端的连接请求(Socketsocket=serverSocket.accept();
服务器通过创建一个内部类(HandleAClient),把客服端的socket传递过来执行。
HandleAClient类
class HandleAClient implements Runnable
{
//A connected socket
private Socket socket;
/**Construct a thread */
public HandleAClient(Socket socket)
{
this.socket = socket;
}
/**Run a thread */
public void run()
{
try
{
//Create data input and output streams
DataInputStream inputFromClient = new DataInputStream(
socket.getInputStream());
DataOutputStream outputToClient = new DataOutputStream(
socket.getOutputStream());
int order = 0;
double amount;
//Continuously serve the client
while(order != 4)
{
//Receive order, amount from the client
order = inputFromClient.readInt();
amount = inputFromClient.readDouble();
if(order == 1)
{
outputToClient.writeDouble(account.getBalance());
}
else if(order == 2)
{
account.withdraw(amount);
outputToClient.writeDouble(account.getBalance());
}
else if(order == 3)
{
account.deposit(amount);
outputToClient.writeDouble(account.getBalance());
}
jta.append("Order received from client: "+
order + '
');
jta.append("Balance is " + account.getBalance() + '
');
}
}
catch(IOException e)
{
System.err.println(e);
}
}
}
而客户端连接上服务器后,创建两个IO流
//IOstreams
DataOutputStreamtoServer=newDataOutputStream(socket.getOutputStream());
DataInputStreamfromServer=newDataInputStream(socket.getInputStream());
即可传输order(菜单选项)和amount
//Sendtheorder,amounttotheserver
toServer.writeInt(order);
toServer.writeDouble(amount);
toServer.flush();
最后再读取balance
balance=fromServer.readDouble();
以上就是动力节点java培训机构的小编针对“Java实战教程,实现网络之并发编程”的内容进行的回答,希望对大家有所帮助,如有疑问,请在线咨询,有专业老师随时为你服务。
你适合学Java吗?4大专业测评方法
代码逻辑 吸收能力 技术学习能力 综合素质
先测评确定适合在学习