Day8.05

来源:互联网 发布:linux查看内存型号 编辑:程序博客网 时间:2024/05/26 02:21

1.wait和notify的使用

当我们在编写多线程的代码的时候,经常会考虑到多线程对共享资源的竞争问题。其中扮演着重要角色的就是Objcet的方法:wait、wait(long waitTime)、notify、notifyAll。开始学习多线程的时候,一直以为是当前线程调用这几个方法,结果老是报IllegalMonitorStateException异常,后查阅资料后发现是没有加锁的问题导致的,再仔细研究后发现,应该是调用竞争资源的相关方法,由竞争资源来等待和通知。下边简要说明下这几个方法的含义:

wait:当一个锁对象执行wait的时候,必须要取的这个锁对象的控制权,一般是放到synchronized(lock)代码中

wait(2000):当前线程每等待2秒的时候,就去检测是否可以获取到竞争资源的控制权,一旦取到竞争资源的控制权,当前线程就可以继续执行,负责继续等待。

notify:通知等待当前竞争资源的一个线程,如果有多个线程等待该资源,只会通知等待队列中的第一个相关线程(不会通知优先级比较高的线程)

notifyALl:通知所有等待该竞争资源的线程(也不会按照线程的优先级来执行)

在编写代码的时候,当我们需要调用以上的方法的时候,一定要对竞争资源进行加锁,如果不加锁的话,则会报 IllegalMonitorStateException 异常。下边是测试代码:

public class Product {    private int number=0;    public int getNumber() {        return number;    }    public void setNumber(int number) {        this.number = number;    }}public class Consumer implements Runnable{    private Product pro;    public Consumer(Product pro) {        this.pro=pro;    }    @Override    public void run() {        while(true){            try {                Thread.sleep(500);            } catch (InterruptedException e1) {                // TODO Auto-generated catch block                e1.printStackTrace();            }            synchronized (pro) {                System.out.println("消费者抢到仓库");                if(pro.getNumber()!=0){                    System.out.println("消费");                    try {                        Thread.sleep(2000);                    } catch (InterruptedException e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                    }                    pro.setNumber(0);                    pro.notify();                }            }        }    }}public class Producer implements Runnable{    private Product pro;    public Producer(Product pro) {        this.pro=pro;    }    @Override    public void run() {        while(true){            synchronized (pro) {                System.out.println("生产者抢到仓库");                if(pro.getNumber()==0){                    System.out.println("生产产品");                    try {                        Thread.sleep(3000);                    } catch (InterruptedException e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                    }                    pro.setNumber(1);                    try {                        pro.wait();                    } catch (InterruptedException e) {                        // TODO Auto-generated catch block                        e.printStackTrace();

2.用多线程TCP协议写的聊天工具

该代码实现1对1聊天,可以一端一次发送多条信息

public class Producer implements Runnable{    private Product pro;    public Producer(Product pro) {        this.pro=pro;    }    @Override    public void run() {        while(true){            synchronized (pro) {                System.out.println("生产者抢到仓库");                if(pro.getNumber()==0){                    System.out.println("生产产品");                    try {                        Thread.sleep(3000);                    } catch (InterruptedException e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                    }                    pro.setNumber(1);                    try {                        pro.wait();                    } catch (InterruptedException e) {                        // TODO Auto-generated catch block                        e.printStackTrace();import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;public class Myserver {    public static void main(String[] args) {        try {            ServerSocket server=new ServerSocket(8080);            Socket socket=server.accept();//等待客户端链接            Thread read=new Thread(new RunnableSocketReceive(socket));            Thread write=new Thread(new RunnableSocketSend(socket));            write.start();            read.start();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.net.ServerSocket;import java.net.Socket;import java.util.Scanner;public class RunnableSocketReceive implements Runnable{    private Socket socket;    public RunnableSocketReceive(Socket socket){        this.socket=socket;    }    @Override    public void run() {        try {            System.out.println("服务器开启");            InputStream sis=socket.getInputStream();            InputStreamReader ss=new InputStreamReader(sis);            BufferedReader as=new BufferedReader(ss);               Scanner scanner=new Scanner(System.in);            while(true){                String s=as.readLine();                System.out.println("客户端来信:"+s);            }        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.net.Socket;import java.net.UnknownHostException;import java.util.Scanner;public class RunnableSocketSend implements Runnable{    private Socket socket;    public RunnableSocketSend(Socket socket){        this.socket=socket;    }    @Override    public void run() {        try {            OutputStream sos = socket.getOutputStream();            OutputStreamWriter writer = new OutputStreamWriter(sos);            BufferedWriter sss = new BufferedWriter(writer);            Scanner scanner = new Scanner(System.in);            while (true) {                String s = scanner.next();                sss.write(s + "\n");                sss.flush();            }        } catch (UnknownHostException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } // ip端口    }}

3.多线程UDP协议聊天工具

该代码实现1对1聊天,可以一端一次发送多条信息

import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.SocketException;public class Receiver1 implements Runnable{    @Override    public void run() {try {        DatagramSocket receiver=new DatagramSocket(8082);           byte[] array=new byte[1024];                while(true){            DatagramPacket packet=new DatagramPacket(array, 1024);            receiver.receive(packet);        byte[] data=packet.getData();                   System.out.println("Receiver接收到的数据\n:"+new String(array,0,packet.getLength()));//String返回字符串长度[]        //以上接收信息        }    } catch (SocketException e) {        // TODO Auto-generated catch block        e.printStackTrace();    } catch (IOException e) {        // TODO Auto-generated catch block        e.printStackTrace();    }    }}import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;import java.net.SocketException;import java.util.Scanner;public class Sender1 implements Runnable{    @Override    public void run() {        try {            DatagramSocket sender = new DatagramSocket();            Scanner scanner = new Scanner(System.in);            while (true) {                                  String s = scanner.next();                byte[] b = s.getBytes();                DatagramPacket packet = new DatagramPacket(b, b.length, InetAddress.getByName("192.168.0.46"), 8084);                sender.send(packet);            }        } catch (SocketException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }}}import chat.practice.lingzhuo.com.MyRead;import chat.practice.lingzhuo.com.MyWrite;public class Test {    public static void main(String[] args) {        Sender1 runnable1=new Sender1();        Receiver1 runnable2=new Receiver1();        Thread chat1=new Thread(runnable1);        Thread chat2=new Thread(runnable2);             chat1.start();        chat2.start();    }}

4.搭建一个简单的聊天界面

1.将WindowsBulider导入Ecliplise
2.建一个JFram文件

这里写图片描述

import java.awt.BorderLayout;import java.awt.EventQueue;import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.border.EmptyBorder;import tcpchat.com.MyClient;import javax.swing.DefaultListModel;import javax.swing.JButton;import java.awt.event.ActionListener;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.net.Socket;import java.net.UnknownHostException;import java.util.Scanner;import java.awt.event.ActionEvent;import javax.swing.JTextField;import javax.swing.JTextArea;import javax.swing.JEditorPane;import javax.swing.JList;public class MyClientim extends JFrame {    private JPanel contentPane;    private Socket socket;    private JTextArea textArea;    private DefaultListModel<String> modle;    /**     * Launch the application.     */    public static void main(String[] args) {        EventQueue.invokeLater(new Runnable() {            public void run() {                try {                    MyClientim frame = new MyClientim();                    frame.setVisible(true);                } catch (Exception e) {                    e.printStackTrace();                }            }        });    }    /**     * Create the frame.     */    public MyClientim() {        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        setBounds(100, 100, 450, 300);        contentPane = new JPanel();        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));        setContentPane(contentPane);        contentPane.setLayout(null);        JButton btnNewButton = new JButton("发送");        btnNewButton.addActionListener(new ActionListener() {            public void actionPerformed(ActionEvent e) {                System.out.println("客户端");                try {                    socket=new Socket("192.168.0.46",8080);                    OutputStream sos = socket.getOutputStream();                    OutputStreamWriter writer = new OutputStreamWriter(sos);                    BufferedWriter sss = new BufferedWriter(writer);                    Scanner scanner = new Scanner(System.in);                    while (true) {                        String s = scanner.next();                        sss.write(s + "\n");                        sss.flush();                    }                } catch (UnknownHostException s) {                    // TODO Auto-generated catch block                    s.printStackTrace();                } catch (IOException s) {                    // TODO Auto-generated catch block                    s.printStackTrace();                } // ip端口            }        });        btnNewButton.setBounds(318, 205, 106, 47);        contentPane.add(btnNewButton);         textArea = new JTextArea();        textArea.setBounds(22, 175, 255, 65);        contentPane.add(textArea);        JList list = new JList();        list.setBounds(22, 10, 255, 155);        modle=new DefaultListModel<>();        list.setModel(modle);        contentPane.add(list);        JButton btnNewButton_1 = new JButton("连接服务器");        btnNewButton_1.addActionListener(new ActionListener() {            public void actionPerformed(ActionEvent e) {                System.out.println("连接服务器");                 try {                    socket=new Socket("192.168.0.46",8080);                    System.out.println("连接服务器成功");                    Thread t=new Thread(new MyClientRead(MyClientim.this));                    t.start();                } catch (UnknownHostException e1) {                    // TODO Auto-generated catch block                    e1.printStackTrace();                } catch (IOException e1) {                    // TODO Auto-generated catch block                    e1.printStackTrace();                }            }        });        btnNewButton_1.setBounds(272, 10, 122, 65);        contentPane.add(btnNewButton_1);    }    public void write(){        try {            OutputStream os=socket.getOutputStream();            BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(os));            System.out.println("客户端发送信息:");            String words=textArea.getText();            bw.write(words+"\n");            bw.flush();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }    public void read(){        try {            InputStream     is = socket.getInputStream();            BufferedReader br=new BufferedReader(new InputStreamReader(is));            String line=br.readLine();            System.out.println(line);        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}public class MyClientRead implements Runnable{private MyClientim client;public MyClientRead(MyClientim client){    this.client=client;}@Overridepublic void run() {    while(true){        client.read();    }}}import java.awt.BorderLayout;import java.awt.EventQueue;import java.awt.TextArea;import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.border.EmptyBorder;import javax.swing.JButton;import java.awt.event.ActionListener;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.net.ServerSocket;import java.net.Socket;import java.util.Scanner;import java.awt.event.ActionEvent;import javax.swing.JTextArea;public class Myserverim extends JFrame {    private JPanel contentPane;    private Socket socket;    private JTextArea textArea;    public boolean isRunning=true;    /**     * Launch the application.     */    public static void main(String[] args) {        EventQueue.invokeLater(new Runnable() {            public void run() {                try {                    Myserverim frame = new Myserverim();                    frame.setVisible(true);                } catch (Exception e) {                    e.printStackTrace();                }            }        });    }    /**     * Create the frame.     */    public Myserverim() {        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        setBounds(100, 100, 559, 480);        contentPane = new JPanel();        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));        setContentPane(contentPane);        contentPane.setLayout(null);        JButton btnNewButton = new JButton("启动服务");        btnNewButton.addActionListener(new ActionListener() {            public void actionPerformed(ActionEvent e) {                System.out.println("点击事件");                try {                    ServerSocket server=new ServerSocket(8080);                     socket=server.accept();                     System.out.println("有客户端连接……");                     Thread t=new Thread(new MyServerRead(Myserverim.this));                     t.start();                } catch (IOException e1) {                    // TODO Auto-generated catch block                    e1.printStackTrace();                }            }        });        btnNewButton.setBounds(10, 0, 398, 162);        contentPane.add(btnNewButton);        JTextArea textArea = new JTextArea();        textArea.setBounds(38, 231, 313, 115);        contentPane.add(textArea);    }public void read(){        try {            InputStream     is = socket.getInputStream();            BufferedReader br=new BufferedReader(new InputStreamReader(is));            String line=br.readLine();            System.out.println(line);        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }    public void write(){        try {            OutputStream os=socket.getOutputStream();            BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(os));            System.out.println("服务器发送信息");            String words=textArea.getText();            bw.write(words+"\n");            bw.flush();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}public class MyServerRead implements Runnable{    private Myserverim server;    public MyServerRead(Myserverim server){        this.server=server;    }    @Override    public void run() {        while(server.isRunning){            server.read();        }    }}
0 0
原创粉丝点击