码迷,mamicode.com
首页 > 编程语言 > 详细

java线程总结

时间:2015-08-09 17:02:02      阅读:133      评论:0      收藏:0      [点我收藏+]

标签:

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();
	   
	}

}

  

 

java线程总结

标签:

原文地址:http://www.cnblogs.com/lzeffort/p/4715267.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!