java多线程

本文详细介绍了Java中实现多线程的两种主要方式:继承Thread类与实现Runnable接口。此外,还探讨了线程相关API的使用,包括线程优先级、守护线程等概念。文章通过具体实例展示了如何利用synchronized关键字解决并发安全问题,并介绍了线程池的应用。

java多线程

  java实现多线程的方式有两种:

     继承Thread类,重写run方法

     实现Runnable接口,并重写run方法

实现多线程的两种方式:

继承Thread:

/**
 * 
 * @Description: 线程的实现方式之继承Thread类
 * @author king-pan   pwpw1218@msn.cn
 * @date 2014年10月11日
 * @version V1.0
 */
public class TestThread {
	public static void main(String[] args) {
		new Thread(){
			public void run() {
				System.out.println("老公: 我犯错了,老婆让我说一百句 i love you");
				System.out.println("************************************");
				for(int i=0;i<100;i++){
					System.out.println("第"+(i+1)+"句: i love you");
				}
				System.out.println("************************************");
				System.out.println("老婆: 态度诚恳,就原谅你了");
			}
		}.start();
	}
}

实现Runnable接口:

/**
 * 
 * @Description: 线程的实现方式之实现Runnable接口
 * @author king-pan pwpw1218@msn.cn
 * @date 2014年10月11日
 * @version V1.0
 */
public class TestThread2 {
	public static void main(String[] args) {
		new Thread(new Runnable() {

			public void run() {
				System.out.println("老公: 我犯错了,老婆让我说一百句 i love you");
				System.out.println("************************************");
				for (int i = 0; i < 100; i++) {
					System.out.println("第" + (i + 1) + "句: i love you");
				}
				System.out.println("************************************");
				System.out.println("老婆: 态度诚恳,就原谅你了");
			}
		}).start();
	}
}

/**
 * 
 * @Description: 线程的实现方式
 * @author king-pan pwpw1218@msn.cn
 * @date 2014年10月11日
 * @version V1.0
 */
public class TestThread3 {
	public static void main(String[] args) {
		// 方式1:继承Thread的形式
		Thread t1 = new Thread() {
			public void run() {
				for (int i = 0; i < 200; i++) {
					System.out.println("你是谁啊?");
				}
			}
		};

		// 方式2:实现Runnable接口的形式
		Runnable runn = new Runnable() {
			public void run() {
				for (int i = 0; i < 200; i++) {
					System.out.println("我是修水管的");
				}
			}
		};
		Thread t2 = new Thread(runn);

		t1.start();
		t2.start();
	}
}


线程相关API:

/**
 * 
 * @Description: 线程相关的api
 * @author king-pan pwpw1218@msn.cn
 * @date 2014年10月11日
 * @version V1.0
 */
public class ThreadApiDemo {
	public static void main(String[] args) {
		// 查看main线程的相关信息
		Thread t = Thread.currentThread();
		long id = t.getId();
		String name = t.getName();//setName();
		int prioirty = t.getPriority();//setPriority();
		System.out.println("id:" + id);
		System.out.println("name:" + name);

		System.out.println("priority:" + prioirty);
		System.out.println("isAlive:" + t.isAlive());
		System.out.println("isDaemon:" + t.isDaemon());//setDaemon();
		System.out.println("isInterrupted:" + t.isInterrupted());
	}
}

/**
 * 
 * @Description: 线程优先级
 * 理论上线程优先级越高的线程,被分配cpu时间片的次数就多
 * 换句话说被执行的次数就多。
 * 优先级1-10
 * 10最大,1最小,默认情况下线程创建出来时优先级是5
 * @author king-pan   pwpw1218@msn.cn
 * @date 2014年10月11日
 * @version V1.0
 */
public class ThreadPriorityDemo {
	public static void main(String[] args) {
		Thread max = new Thread(){
			public void run(){
				for(int i=0;i<1000;i++){
					System.out.println("max");
				}
			}
		};
		Thread norm = new Thread(){
			public void run(){
				for(int i=0;i<1000;i++){
					System.out.println("norm");
				}
			}
		};
		Thread min = new Thread(){
			public void run(){
				for(int i=0;i<1000;i++){
					System.out.println("min");
				}
			}
		};
		
		max.setPriority(Thread.MAX_PRIORITY);
		min.setPriority(Thread.MIN_PRIORITY);
		
		min.start();
		norm.start();
		max.start();
	}
}

/**
 * 
 * @Description: 守护线程(后台线程)
 * @author king-pan   pwpw1218@msn.cn
 * @date 2014年10月11日
 * @version V1.0
 */
public class ThreadDaemonDemo {
	public static void main(String[] args) {
		/*
		 * rose的表演者:前台线程
		 */
		Thread rose = new Thread(){
			public void run(){
				for(int i=0;i<10;i++){
					System.out.println(
						"rose:let me go!"
					);
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
					}
				}
				System.out.println(
					"rose:AAAAAAaaaaaa......");
				System.out.println(
					"旁白:噗通!");		
			}
		};
		
		Thread jack = new Thread(){
			public void run(){
				while(true){
					System.out.println(
						"jack:you jump!i jump!");
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
					}
				}
			}
		};
		
		rose.start();
		/*
		 * 设置为守护线程应该在start()方法之
		 * 前被调用
		 */
		jack.setDaemon(true);
		
		jack.start();
	}
}

CurrentThread:

/**
 * 
 * @Description: 当前线程
 * @author king-pan pwpw1218@msn.cn
 * @date 2014年10月11日
 * @version V1.0
 */
public class CurrentThreadDemo {
	public static void main(String[] args) {
		Thread t = Thread.currentThread();
		System.out.println("运行main方法的线程是:" + t);
		test();
		// 自己创建的线程
		Thread myT = new Thread() {
			public void run() {
				Thread tt = Thread.currentThread();
				System.out.println("运行run方法的线程是:" + tt);
				test();
			}
		};
		myT.start();
	}

	public static void test() {
		/*
		 * 获取运行Thread.currentThread()这个方法 的线程,并返回
		 */
		Thread t = Thread.currentThread();
		System.out.println("运行currentThread方法的线程是" + t);
	}
}


 Join:

/**
 * 
 * @Description:  join方法可以让当前线程在某一个线程上等待,直到其
 * 结束后,再让当前线程继续执行。
 * join会引起线程阻塞
 * @author king-pan   pwpw1218@msn.cn
 * @date 2014年10月11日
 * @version V1.0
 */
public class ThreadJoinDemo {
	// 表示图片是否下载完毕了
	private static boolean isFinish = false;

	public static void main(String[] args) {
		final Thread download = new Thread() {
			public void run() {
				System.out.println("down:开始下载图片...");
				for (int i = 1; i <= 100; i++) {
					System.out.println("down:已下载" + i + "%");
					try {
						Thread.sleep(50);
					} catch (InterruptedException e) {
					}
				}
				System.out.println("down:图片下载完毕!");
				isFinish = true;// 表示图片下载完毕了
			}
		};

		Thread show = new Thread() {
			public void run() {
				System.out.println("show:准备显示图片...");
				// 首先要等待下载线程将图片下载完毕
				try {
					/*
					 * 这里阻塞的是show线程,直到download 线程执行完毕后,join方法才会解除 阻塞
					 */
					download.join();
				} catch (InterruptedException e) {
				}
				if (!isFinish) {
					throw new RuntimeException("图片没有下载完毕!显示失败!");
				}
				System.out.println("show:已经显示图片");
			}
		};

		download.start();
		show.start();

	}
}

/**
 * 
 * @Description:  join方法可以让当前线程在某一个线程上等待,直到其
 * 结束后,再让当前线程继续执行。
 * join会引起线程阻塞
 * @author king-pan   pwpw1218@msn.cn
 * @date 2014年10月11日
 * @version V1.0
 */
public class ThreadJoinDemo2 {
	public static void main(String[] args)throws Exception {
		 Thread download = new Thread() {
			public void run() {
				System.out.println("down:开始下载图片...");
				for (int i = 1; i <= 100; i++) {
					System.out.println("down:已下载" + i + "%");
					try {
						Thread.sleep(50);
					} catch (InterruptedException e) {
					}
				}
				System.out.println("down:图片下载完毕!");
			}
		};

		Thread show = new Thread() {
			public void run() {
				System.out.println("show:已经显示图片");
			}
		};

		download.start();
		download.join();
		show.start();
		show.join();

	}
}

/**
 * 
 * @Description: wait()与notify()方法是在Object上定义的方法
 * 换句话说线程可以在任意对象上等待,在特殊情况下,wait,notity的性能高于
 * join,join是需要等待线程执行完成,wait,notify 是可以在线程的任何位置
 * (同步块中)
 * @author king-pan   pwpw1218@msn.cn
 * @date 2014年10月11日
 * @version V1.0
 */
public class WaitAndNotityDemo {
	private static boolean isFinish = false;

	public static void main(String[] args) {
		final Object obj = new Object();
		Thread download = new Thread() {
			public void run() {
				System.out.println("down:开始下载图片...");
				for (int i = 1; i <= 100; i++) {
					System.out.println("down:已下载" + i + "%");
					try {
						Thread.sleep(50);
					} catch (InterruptedException e) {
					}
				}
				System.out.println("down:图片下载完毕!");
				isFinish = true;// 表示图片下载完毕了
				// 通知显示线程可以显示图片了!
				synchronized (obj) {
					obj.notify();
				}

				System.out.println("down:开始下载附件...");
				for (int i = 1; i <= 100; i++) {
					System.out.println("down:已下载" + i + "%");
					try {
						Thread.sleep(50);
					} catch (InterruptedException e) {
					}
				}
				System.out.println("down:附件下载完毕!");

			}
		};

		Thread show = new Thread() {
			public void run() {
				System.out.println("show:准备显示图片...");
				// 首先要等待下载线程将图片下载完毕
				try {
					synchronized (obj) {
						obj.wait();
					}
				} catch (InterruptedException e) {
				}
				if (!isFinish) {
					throw new RuntimeException("图片没有下载完毕!显示失败!");
				}
				System.out.println("show:已经显示图片");
			}
		};

		download.start();
		show.start();
	}
}

线程的资源共享问题:

/**
 * 
 * @Description: 线程之间资源共享的问题
 * 非静态资源
 * 静态资源(特性就是共享)
 * @author king-pan   pwpw1218@msn.cn
 * @date 2014年10月11日
 * @version V1.0
 */
public class Table {
	private int beans = 20;
	/*
	 * 非静态方法中所的对象是:
	 * 线程调用哪个对象的getBean()方法,锁的就是哪个
	 * 对象,这个例子中锁的就是main方法中第一行创建的
	 * table对象。
	 */
	public synchronized int getBean(){
		if(beans==0){
			throw new RuntimeException("没有豆子了");
		}
		Thread.yield();
		return beans--;
	}
	
	public static void main(String[] args) {
		final Table table = new Table();
		Thread t1 = new Thread(){
			public void run(){
				while(true){
					int bean = table.getBean();
					Thread.yield();
					System.out.println(
						getName()+":"+bean);
				}
			}
		};
		Thread t2 = new Thread(){
			public void run(){
				while(true){
					int bean = table.getBean();
					System.out.println(
						getName()+":"+bean);
				}
			}
		};
		t1.start();
		t2.start();
	}
}

/**
 * 
 * @Description: 线程之间资源共享的问题
 * 非静态资源
 * 静态资源(特性就是共享)
 * @author king-pan   pwpw1218@msn.cn
 * @date 2014年10月11日
 * @version V1.0
 */
public class Table {
	
	/*
	 * 静态方法中锁的对象是:
	 * 线程调用哪个对象的getBean()方法,锁的就是哪个
	 * 对象,这个例子中锁的就是main方法中第一行创建的
	 * table对象。
	 */
    static class Bean implements Runnable{
    	private static int beans = 20;
		public synchronized int getBean(){
			if(beans==0){
				throw new RuntimeException("没有豆子了");
			}
			Thread.yield();
			return beans--;
		}
		public void run() {
			while(true){
				int bean = getBean();
				Thread.yield();
				System.out.println(
					Thread.currentThread().getName()+":"+bean);
			}
		}
    }
	
	public static void main(String[] args) {
		final Bean bean=new Bean();
		Thread t1 = new Thread(bean);
		Thread t2 = new Thread(bean);
		t1.start();
		t2.start();
	}
}


资源共享问题,最好是使用静态资源,实现Runnable接口



线程安全问题:

/**
 * 
 * @Description: 多线程并发安全问题
 * 多线程访问统一资源时就会产生并发安全问题
 * 解决办法:将异步操作变为同步操作
 * @author king-pan   pwpw1218@msn.cn
 * @date 2014年10月11日
 * @version V1.0
 */
public class ThreadSynchronizedDemo1 {
	private static int beans = 20;

	public static void main(String[] args) {
		Thread t1 = new Thread() {
			public void run() {
				while (true) {
					int bean = getBean();
					System.out.println(getName() + ":" + bean);
				}
			}
		};
		Thread t2 = new Thread() {
			public void run() {
				while (true) {
					int bean = getBean();
					Thread.yield();
					System.out.println(getName() + ":" + bean);
				}
			}
		};
		t1.start();
		t2.start();
	}

	/*
	 * 静态方法上被声明synchronized后,该静态方法 变为同步,当线程执行该方法使,会把当前类对象锁住
	 * 因为一个类只有一个类对象,所以其他线程发现该类对象 被锁住后,该方法就进不去了。从而保证同一个方法不能 被多个线程同时访问内部。
	 * 不了解反射时,可能不清楚类对象,可以简单理解为将 静态方法所属的类加所,因为类Sync只有一个。
	 */
	public synchronized static int getBean() {
		if (beans == 0) {
			throw new RuntimeException("没豆子了");
		}
		Thread.yield();
		return beans--;
	}
}

/**
 * 
 * @Description: 减小同步范围可以提高代码执行效率
 * @author king-pan   pwpw1218@msn.cn
 * @date 2014年10月11日
 * @version V1.0
 */
public class ThreadSynchronizedDemo2 {
	public static void main(String[] args) {
		final ThreadSynchronizedDemo2 demo = new ThreadSynchronizedDemo2();
		Thread t1 = new Thread(){
			public void run(){
				try {
					demo.buy();
				} catch (InterruptedException e) {
				}
			}
		};
		Thread t2 = new Thread(){
			public void run(){
				try {
					demo.buy();
				} catch (InterruptedException e) {
				}
			}
		};
		
		t1.start();
		t2.start();
	}
	/*
	 *  买衣服
	 */
	public void buy() throws InterruptedException{
		Thread t = Thread.currentThread();
		System.out.println(t.getName()+"正在挑衣服...");
		Thread.sleep(5000);
		/*
		 * 同步块要求锁的对象多线程要看到的是同一个
		 * 才有效果。否则没意义。
		 * synchronized (new Object()) {
		 * 上面的写法就是个错误的!
		 */
		synchronized (this) {
			System.out.println(t.getName()+"正在试衣服...");
			Thread.sleep(5000);
		}
		
		System.out.println(t.getName()+"结账。");
	}
}

/**
 * 
 * @Description: synchronized又称为互斥锁
 * @author king-pan pwpw1218@msn.cn
 * @date 2014年10月11日
 * @version V1.0
 */
public class ThreadSynchronizedDemo3 {
	public static void main(String[] args) {
		final ThreadSynchronizedDemo3 demo = new ThreadSynchronizedDemo3();
		Thread t1 = new Thread() {
			public void run() {
				demo.foo();
			}
		};
		Thread t2 = new Thread() {
			public void run() {
				demo.boo();
			}
		};
		t1.start();
		t2.start();
	}

	public void foo() {
		synchronized (this) {
			System.out.println("foo start");
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
			}
			System.out.println("foo end");
		}
	}

	public void boo() {
		synchronized (this) {
			System.out.println("boo start");
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
			}
			System.out.println("boo end");
		}
	}
}

线程池:

/**
 * 
 * @Description: 线程池
 * @author king-pan   pwpw1218@msn.cn
 * @date 2014年10月12日
 * @version V1.0
 */
public class ExecutorServiceDemo {
	public static void main(String[] args) {
		/*
		 * 创建一个固定大小的线程池 线程数为2
		 */
		ExecutorService threadPool = Executors.newFixedThreadPool(2);

		for (int i = 0; i < 5; i++) {
			Runnable run = new Runnable() {
				public void run() {
					Thread t = Thread.currentThread();
					System.out.println("运行当前任务的线程是:" + t);
					try {
						Thread.sleep(5000);
					} catch (InterruptedException e) {
					}
					System.out.println(t + "运行完任务了!");
				}
			};
			threadPool.execute(run);
		}

	}
}


转载于:https://my.oschina.net/KingPan/blog/326930

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值