首页 课程 师资 教程 报名

Java实战教程,实现网络之并发编程

  • 2020-05-12 16:14:42
  • 2199次 动力节点

1.并发与并行

个人理解并发就是在时间上运行程序(即不同任务在不同时间片上运行),并行就是在空间上运行程序(即不同任务在不同处理器或计算机上运行)。

2.Java中的Thread类

(1)Thread类通过实现Runnable接口

(2)线程池(ThreadPool)用来管理线程的数量

我们先用一个例子实现:

  • 创建并启动100个线程,每个线程都往同一个账户添加一元。
  • 定义一个名为Account类模拟账户,一个名为AddAYuanTask的类用来向账户里添加一元。

程序如下

第一版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,这是个错误的结果,如果一个类的对象在多线程程序中导致竞争状态,则称这个类为线程不安全的。所以这个任务是线程不安全的。

3.用同步完善程序

用互斥锁来实现同步,即在一任务开始执行时加锁,执行完毕后释放锁。在释放锁之前其它任务无法执行。同步完全可以避免竞争状态的产生,但有的时候还需要线程之间的相互合作。

然后增加一个向账户提款(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);
            }
        }
    }

4.客户端/服务器的网络应用

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大专业测评方法

代码逻辑 吸收能力 技术学习能力 综合素质

先测评确定适合在学习

在线申请免费测试名额
价值1998元实验班免费学
姓名
手机
提交