标签:
1.在java使用线程的方式有2种:
(1)继承Thread类
(2)实现Runnable接口
下面用例子来说明:
方式一:
class Test extends Thread{ public void run(){ Sysout.println("Thread test ...") } } public class ThreadTest{ public static void main(String[] args){ Thread t = new Test(); t.start(); } }
方式二:
class Test implements Runnable{ public void run(){ System.out.println("Runnable test..."); } } public class ThreadTest{ public static void main(String[] args){ Test t = new Test(); Thread th = new Thread(t); th.start(); } }
墙裂坚毅是用二种方式,由于java中的类都是单继承,多实现,当一个类继承其他类时,还想实现多线程,就不能用继承,只能用实现接口。
2.线程存在一些安全问题
一个购票的实例:
class Ticket implements Runnable{ private int ticket = 100; @Override public void run() { while(true){ if(ticket>0){ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"---"+ticket--); } } } } public class TicketDemo { public static void main(String[] args) { Ticket ticket = new Ticket(); Thread t = new Thread(ticket); Thread t2 = new Thread(ticket); Thread t3 = new Thread(ticket); Thread t4 = new Thread(ticket); t.start(); t2.start(); t3.start(); t4.start(); } }
运行后会出现:
0和-1也出现了,这是不应该出现的。
解释原因:假设现在只有一张票了,被线程1抢到,由于 Thread.sleep(10); 导致其他线程也进入,当Thread-1醒来将票数减去一,当前票数为0,但是当其他线程醒来,再去减一是,票数早已为0,这就是导致票数为0,-1的原因。
怎么解决? 在操作数据的地方加入同步代码块。
public void run() { while(true){ synchronized(this){//同步代码块 if(ticket>0){ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"---"+ticket--); } } } }
如果将run方法加上static 同步代码块上不能用this,由于类加载的原因,应该使用Ticket.class对象,在类加载的时候,类的字节码对象已经存在,但是实例对象不存在,需要通过new 关键字创建。
下面是一张线程的图:
最后一个例子是用线程和网络编程结合的一个聊天代码:(如果两个客户端通信记得修改ip)
package com.core.net; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; class MSend implements Runnable{ private DatagramSocket socket; public MSend(DatagramSocket socket){ this.socket = socket; } @Override public void run() { BufferedReader reader = null; try { reader = new BufferedReader(new InputStreamReader(System.in)); String line = null; while((line = reader.readLine())!=null){ if("886".equals(line)){ break; } byte[] buf = line.getBytes(); DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.23.255"), 8887); socket.send(dp); } } catch (Exception e) { throw new RuntimeException("发送端失败"); }finally{ try { reader.close(); } catch (IOException e) { e.printStackTrace(); } socket.close(); } } } class MRecevice implements Runnable{ private DatagramSocket socket; public MRecevice(DatagramSocket socket){ this.socket = socket; } @Override public void run() { try { while(true){ byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf,buf.length); socket.receive(dp); String ip = dp.getAddress().getHostAddress(); String data = new String(dp.getData(),0,dp.getLength()); System.out.println(ip+":"+data); } } catch (Exception e) { throw new RuntimeException("接受端失败"); } } } public class ChatDemo { public static void main(String[] args) throws Exception { DatagramSocket send = new DatagramSocket(); DatagramSocket rece = new DatagramSocket(8887); new Thread(new MSend(send)).start(); new Thread(new MRecevice(rece)).start(); } }
标签:
原文地址:http://www.cnblogs.com/lzeffort/p/4715267.html