java多线程知识汇总

1. 线程创建方式

1.  new Thread(new Runnable(){}).start();
2.  new Thread(){public void run(){}}.start(); 

第一种方式更符合面向对象,因为将线程与线程运行的对象分来了

2. synchronized关键字,用于实现代码互斥,多线程时,这段代码同一时间只有一个线程可以访问

可以修饰代码块或者方法

3. 传统线程同步通信技术


package com.wzz.xiancheng;
/**
 * 子线程运行10次,主线程运行100次,如此循环50次
 * @author wzz
 *
 */
public class TrainThreadComm {

	public static void main(String[] args) {
		
		final ExecData data = new ExecData();
		//子线程
		new Thread(new Runnable(){

			@Override
			public void run() {
				for(int i=0; i<50; i++){
					data.dataSub(i);
				}
			}
			
		}).start();
		//主线程
		for(int i=0; i<50; i++){
			data.dataMain(i);
		}

	}
}

class ExecData{
	private boolean flag = true;
	private String data = "aaa";
	/*
	 * 子线程运行
	 */
	public synchronized void dataSub(int k){
		while(!flag){
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		for(int i=0; i<10; i++){
			System.out.println(k+"_子线程运行:"+data+",第"+i+"次");
		}
		this.flag = false;
		this.notify();
	}
	/*
	 * 主线程运行
	 */
	public synchronized void dataMain(int k){
		while(flag){
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		for(int i=0; i<100; i++){
			System.out.println(k+"_主线程运行:"+data+",第"+i+"次");
		}
		this.flag = true;
		this.notify();
	}
}

1. 讲需要操作的数据和操作方法封装在一个类中,然后实例化对象后,新建线程去访问
2. 利用notify()和wait()方法进行运行和等待的调度
3. bool变量设定执行顺序


4. 线程范围内共享变量的概念与作用



package com.wzz.xiancheng;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

public class ThreadShareDataUseMap {

	private static Map<Thread, String> map = new HashMap();
	
	public static void main(String[] args) {
		for(int i=0; i<2; i++){
			new Thread(new Runnable(){
				@Override
				public void run() {
					map.put(Thread.currentThread(), new Random().nextInt()+"");
					
					A.get();
					B.get();
				}
			}).start();
		}
	}
	
	static class A{
		public static void get(){
			String data = map.get(Thread.currentThread());
			System.out.println("A:"+Thread.currentThread().getId()+","+data);
		}
	}
	
	static class B{
		public static void get(){
			String data = map.get(Thread.currentThread());
			System.out.println("B:"+Thread.currentThread().getId()+","+data);
		}
	}

}

1. 利用map,线程为key,数据为value


5. ThreadLocal类及应用技巧



package com.wzz.ttt;

import java.util.Random;

public class ThreadS {

	public static void main(String[] args) {
		for(int i=0; i<3; i++){
			new Thread(new Runnable() {
				
				@Override
				public void run() {
					MyThreadScopeData.getThreadInstance().setAge(new Random().nextInt(100));
					MyThreadScopeData.getThreadInstance().setName(Thread.currentThread().getName());
					
					get();
				}
			}).start();
		}
	}
	public static void get(){
		int age = MyThreadScopeData.getThreadInstance().getAge();
		String name = MyThreadScopeData.getThreadInstance().getName();
		
		System.out.println(name+":"+age);
	}
}

class MyThreadScopeData{
	private MyThreadScopeData(){}
	public static /*synchronized*/ MyThreadScopeData getThreadInstance(){
		MyThreadScopeData instance = map.get();
		if(instance == null){
			instance = new MyThreadScopeData();
			map.set(instance);
		}
		return instance;
	}
	//private static MyThreadScopeData instance = null;//new MyThreadScopeData();
	private static ThreadLocal<MyThreadScopeData> map = new ThreadLocal<MyThreadScopeData>();
	
	private String name;
	private int age;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
}
1. ThreadLocal类来共享数据,


6. 多线程数据共享


package com.wzz.xiancheng;
/**
 * 两个线程,一个++,一个--
 * @author wzz
 *
 */
public class MultiThreadShareData {

	private static ShareData1 data1 = new ShareData1();
	
	public static void main(String[] args) {
		ShareData1 data2 = new ShareData1();
		/*
		 * 写两个runnable
		 */
		new Thread(new MyRunnable1(data2)).start();
		new Thread(new MyRunnable2(data2)).start();
		/*
		 * 直接调用数据的方法
		 */
		final ShareData1 data1 = new ShareData1();
		new Thread(new Runnable(){
			@Override
			public void run() {
				data1.decrement();
				
			}
		}).start();
		new Thread(new Runnable(){
			@Override
			public void run() {
				data1.increment();
				
			}
		}).start();

	}

}
	/**
	 * ++线程runnnable
	 * @author wzz
	 *
	 */
	class MyRunnable1 implements Runnable{
		private ShareData1 data1;
		public MyRunnable1(ShareData1 data1){
			this.data1 = data1;
		}
		public void run() {
			data1.decrement();
			
		}
	}
	/**
	 * --线程runnable
	 * @author wzz
	 *
	 */
	class MyRunnable2 implements Runnable{
		private ShareData1 data1;
		public MyRunnable2(ShareData1 data1){
			this.data1 = data1;
		}
		public void run() {
			data1.increment();
		}
	}

	class ShareData1{
		private int j = 0;
		public synchronized void increment(){
			j++;
		}
		
		public synchronized void decrement(){
			j--;
		}
	}
1. 把数据操作封装成一个类,并实例化
2. 可以实例化数据类后,线程直接调用对象的操作方法
3. 也可以将不通的操作放入不同的runnable对象


7. java5原子性操作类的应用


AtominInteger ai = new AtominInteger();
Atomin*******



8. java5线程并发库的应用

线程池:
<span style="white-space:pre">		</span>public static void main(String[] args) {
			//ExecutorService threadPool = Executors.newFixedThreadPool(3);//固定数量
			//ExecutorService threadPool = Executors.newCachedThreadPool();//缓冲型,根据需要新建多个线程,不需要时候再释放掉
			ExecutorService threadPool = Executors.newSingleThreadExecutor();//单个线程,当线程死掉时,重启一条新的线程
			for(int i=0; i<10; i++){
				final int k = i;
				threadPool.execute(new Runnable() {
					
					@Override
					public void run() {
						System.out.println(Thread.currentThread().getId()+"_"+k);
					}
				});
			}
			threadPool.shutdown();//当线程都完成时,关掉线程池
			//threadPool.shutdownNow();//立即关掉线程池
		}




9. CallableAndFuture



代码见---9. CallableAndFuture

	/*
		单一任务的
	
	*/
	ExecutorService threadPool =  Executors.newSingleThreadExecutor();
	Future<String> future =
		threadPool.submit(
			new Callable<String>() {
				public String call() throws Exception {//这里面写线程任务代码
					Thread.sleep(2000);
					return "hello";
				};
			}
	);
	System.out.println("等待结果");
	try {
		System.out.println("拿到结果:" + future.get());//get方法会在线程执行完毕后才执行
	} catch (InterruptedException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	
	
	/*
		批量放入多个线程,并取出多个结果,取出顺序按照线程执行顺序
	
	*/
	ExecutorService threadPool2 =  Executors.newFixedThreadPool(10);
	CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(threadPool2);
	for(int i=1;i<=10;i++){
		final int seq = i;
		completionService.submit(new Callable<Integer>() {
			@Override
			public Integer call() throws Exception {
				Thread.sleep(new Random().nextInt(5000));
				return seq;
			}
		});
	}
	for(int i=0;i<10;i++){
		try {
			System.out.println(
					completionService.take().get());
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}


10. java5的线程锁技术



相当于synchronized,但是更符合面向对象

Lock lock = new ReentrantLock();
lock.lock();
lock.unlock();


11. 读写锁的使用



读与读之间可以并,读写,写与写互斥

ReadWriteLock rwl = new ReentrantReadWriteLock();

rwl.readLock().lock();
rwl.readLock().unlock();

rwl.writeLock().lock();
rwl.writeLock().unlock();

一个缓存器的例子,代码见---10. 一个缓存器的例子

public class CacheDemo {

	private Map<String, Object> cache = new HashMap<String, Object>();
	public static void main(String[] args) {
		

	}

	private ReadWriteLock rwl = new ReentrantReadWriteLock();
	public  Object getData(String key){
		rwl.readLock().lock();
		Object value = null;
		try{
			value = cache.get(key);
			if(value == null){
				rwl.readLock().unlock();
				rwl.writeLock().lock();
				try{
					if(value==null){
						value = "aaaa";//实际失去queryDB();
					}
				}finally{
					rwl.writeLock().unlock();
				}
				rwl.readLock().lock();
			}
		}finally{
			rwl.readLock().unlock();
		}
		return value;
	}
}


12. Condition

1. 实例实质上被绑定到一个锁上。要为特定 Lock 实例获得 Condition 实例,请使用其 newCondition() 方法
Lock lock = new ReentrantLock();
Conditicon con = lock.newCondition();
2. Condition 应该总是在一个循环中被等待,并测试正被等待的状态声明
while (count == items.length) {
con.await();
}
3. 主要方法
1. await() 造成当前线程在接到信号或被中断之前一直处于等待状态。
2. signal()  唤醒一个等待线程。
3. signalAll() 唤醒所有等待线程。

方法类似于(wait、notify 和 notifyAll)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值