博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java并发相关(1)---线程相关基本api使用
阅读量:4075 次
发布时间:2019-05-25

本文共 9247 字,大约阅读时间需要 30 分钟。

线程相关基本api使用

一、threadLocal

1、概念:是线程局部变量,不管哪个线程访问此变量,得到的值都是哪个线程当前的存储的值,每个线程有一个ThreadLocalMap , 它可以存此线程的变量,而如果把key值做成所有线程共享的静态变量或其他,这样就能以一个相同的key在不同的线程中存不同的对象。

2、使用:

public class T00_ThreadLocal {		/**演示*/	public static void main(String args[]){		Thread t1 = new Thread(new Run1());		Thread t2 = new Thread(new Run2());		t1.start();		t2.start();	}}class TcUtil{	private static ThreadLocal
tc = new ThreadLocal
();//泛型设置成什么,就能往ThreadLocalMap中设置什么值 public static ThreadLocal
getTc() { return tc; }}/**线程1*/class Run1 implements Runnable{ @Override public void run() { TcUtil.getTc().set("我是线程1的值"); for (int i = 0; i < 5; i++) { try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();} System.out.println("线程1倒计时"+(5-i)+"秒"); } System.out.println("拿线程1的值:"+TcUtil.getTc().get()); }}/**线程2*/class Run2 implements Runnable{ @Override public void run() { TcUtil.getTc().set("我是线程2的值"); for (int i = 0; i < 5; i++) { try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();} System.out.println("线程2倒计时"+(5-i)+"秒"); } System.out.println("拿线程2的值:"+TcUtil.getTc().get()); }}

二、创建线程的方式:

概述:创建线程的方式

 * 1、继承thread,重写run()方法,调用thread.start()开启线程
 * 2、实现Runable,实现run()方法,调用thread.start()开启线程
 * 3、实现Callable,实现call()方法,实际上是给Task的run调用。

public class T01_CreateThread {	public static void main(String[] args) throws ExecutionException, InterruptedException {		// 方式一:Runnable		Thread t1 = new Thread(new Runnable() {			@Override			public void run() {				System.out.println("Runnable版");			}		});		t1.start();		Thread t2 = new Thread(() -> {			System.out.println("RunnableJDK8版");		});		t2.start();		// 方式二:继承Thread		Thread t3 = new Thread() {			public void run() {				System.out.println("Thread版");			}		};		t3.start();		// 方式三、实现Callable		FutureTask
futureTask = new FutureTask
(new Callable
() { @Override public Integer call() throws Exception { Thread.sleep(2000); return 1; } }); Thread thread = new Thread(futureTask); thread.start(); Integer result = futureTask.get(); System.out.println("这里是被阻塞的"); System.out.println("futureTask的执行结果" + result); } }

三、线程方法join、sleep、yield

 * 概述:sleep可以释放当前cup资源多少时间,去干其他活。

 *          yield也是释放当前cup资源,但是放弃的时间不确定。
 *          join-在main线程调用thead.join,那么main线程会等待thead线程执行完才返回。

public class T02_sleep_join_yield {		public static void main(String[] args) throws InterruptedException {		// 1、sleep停顿1000毫秒		Thread.sleep(1000);		Thread t1 = new Thread("线程1"){			public void run(){				System.out.println("线程1开始了");				try {	sleep(1800);} catch (InterruptedException e) {	e.printStackTrace();}				System.out.println("线程1执行完了");			}		};		t1.start();		// 2、join主线程2000毫秒		t1.join(2000); // 这里注意,因为thread线程干活需要1800,如果join时间少于这个数值,那么主线程会提前结束。		System.out.println("主线程结尾!");				System.out.println("演示yield,实际上这里没演示出什么效果!!");				Thread t2 = new Thread("线程2"){			public void run(){				for (int i = 0; i < Integer.MAX_VALUE; i++) {					System.out.println("线程2执行,值:"+i);					mySleep(1);				}			}		};				Thread t3 = new Thread("线程3"){			public void run(){				for (int i = 0; i < Integer.MAX_VALUE; i++) {					System.out.println("线程3执行,值:"+i);					mySleep(1);					if(i%10==0) {						yield();					}				}			}		};		t2.start();t3.start();		t2.join();		t3.join();	}		public static void mySleep(long millisecond) {		long begin = System.currentTimeMillis();		while(true) {			long end = System.currentTimeMillis();			if(end - begin > millisecond) {				break;			}		}	}	}

四、synchronized

概述:synchronized关键字是用来加锁,使用在方法上或代码块中,如果加在实例方法上,那么锁就是此实例对象。如果加在静态方法上,那么锁就是类class对象。代码块中的锁为代码块中指定。

范例:

private static class Ticket extends Thread{		public Ticket(String name){			super(name);		}		private static volatile int ticket = 100; //一共有100张票,是静态类共享数据。		public void run(){			while(true){				synchronized (Ticket.class) { //同步的锁需要class,因为是此类多个对象的此值需要抢占此资源					if(ticket==0){						break;					}					System.out.println(getName()+"这是第"+ticket--+"张票");				}			}		}	}		public static void main(String[] args) {		new Ticket("线程1").start();		new Ticket("线程2").start();	}

五、死锁演示:

概述:是由2个或2个以上线程由于资源竞争,处于互相等待的情况。

private static String lock1 = "锁1";		private static String lock2 = "锁2";		public static void main(String[] args){		new Thread(){			public void run() {				while(true){					synchronized (lock1){						System.out.println(getName()+"获取:"+lock1+" 等锁:"+lock2);						synchronized (lock2) {							System.out.println(getName()+"获取"+lock2);						}					}				}			}		}.start();				new Thread(){			public void run() {				while(true){					synchronized (lock2){						System.out.println(getName()+"获取:"+lock2+" 等锁:"+lock1);						synchronized (lock1) {							System.out.println(getName()+"获取"+lock1);						}					}				}			}		}.start();	}

六、Wait_Notify

概述:wait方法可以让当前线程放弃持有的锁,并且进入等待池,只有线程的方法调用notify或notifyAll时,

 * 才可以把这些等待的对象重新竞争锁,而notify只能唤醒一个线程。注意:等待和唤醒必须是同一个锁。

public static void main(String[] args) {		Person p = new Person();		Produce produce = new Produce(p);		Consume consume = new Consume(p);		produce.start();		consume.start();	}		private static class Person {		private String name;		private int age;		private volatile boolean flag; // 标记用来判断当前是应该set还是get		public synchronized void set(String name, int age) throws InterruptedException {			if (flag) {				this.wait();			}			this.name = name;			this.age = age;			this.flag = false;			this.notify();		}		public synchronized void read() throws InterruptedException {			if (!flag) {				this.wait();			}			System.out.println("name is:" + this.name + ":" + "age is:" + this.age);			this.flag = false;			this.notify();		}	}		private static class Produce extends Thread{		Person p;		Produce(Person p) {			this.p = p;		}		@Override		public void run() {			while (true) {				try {					p.set("zhangsan", 18);				} catch (InterruptedException e) {					e.printStackTrace();				}			}		}	}		private static class Consume extends Thread {		Person p;		Consume(Person p) {			this.p = p;		}		@Override		public void run() {			while (true) {				try {					p.read();				} catch (InterruptedException e) {					e.printStackTrace();				}			}		}	}

七、生成者消费者

public class T07_Produce {		public static void main(String args[]){		// 仓库对象  	    Storage storage = new Storage();  		    // 生产者对象  	    Producer p1 = new Producer(storage);  	    Producer p2 = new Producer(storage);  	    Producer p3 = new Producer(storage);  	    	    // 消费者对象  	    Consume c1 = new Consume(storage);  	    Consume c2 = new Consume(storage);  	    Consume c3 = new Consume(storage);  	    	    // 设置生产者产品生产数量  	    p1.setNum(40);  	    p2.setNum(23);  	    p3.setNum(40);  		    // 设置消费者产品消费数量  	    c1.setNum(50);  	    c2.setNum(20);  	    c3.setNum(30);  		    // 线程开始执行  	    c1.start();  	    c2.start();  	    c3.start();  	    p1.start();  	    p2.start();  	    p3.start();  	}}/** * 库存对象 */class Storage{  	 private final int MAX_SIZE = 100;	 private LinkedList list = new LinkedList();	 public void produce(int num){        synchronized (list){ 	        while(list.size() + num > MAX_SIZE){	        	System.out.println("【要生产的产品数量】:" + num + "【库存量】:" + list.size() + "暂时不能执行生产任务!");  	        	try{ list.wait();}catch (InterruptedException e){  e.printStackTrace(); }  	        }  	        for (int i = 1; i <= num; ++i){	            list.add(new Object());	        }  	        System.out.println("【已经生产产品数】:" + num + "【现仓储量为】:" + list.size());	        list.notifyAll();        }      }	public void consume(int num) {		synchronized (list) {			while(list.size()

八、interrupt相关方法

 * 概述:线程中断就是维护了一个线程的中断标记,没有中断就是false。

 * 他们一共有三个方法:    
 *     静态方法,Thread.interrupted(); // 判断当前线程是否中断,如果中断,清除中断,即中断标记变成false。
 *     实例方法,thread.isInterrupted(); // 判断当前线程是否中断。中断标记不变。
 *     实例方法,thread.interrupt(); // 设置为中断,中断标记为ture。

* interrupt相关方法 * 概述:线程中断就是维护了一个线程的中断标记,没有中断就是false。 * 他们一共有三个方法:	 * 	静态方法,Thread.interrupted(); // 判断当前线程是否中断,如果中断,清除中断,即中断标记变成false。 * 	实例方法,thread.isInterrupted(); // 判断当前线程是否中断。中断标记不变。 * 	实例方法,thread.interrupt(); // 设置为中断,中断标记为ture。 */public class T09_interrupt {		public static void main(String[] args) throws InterruptedException {		boolean interrupted = Thread.interrupted();		System.out.println(interrupted); // false		boolean isInterrupted = Thread.currentThread().isInterrupted(); // 线程是否中断		System.out.println(isInterrupted); // false		Thread.currentThread().interrupt(); // 设置成中断		isInterrupted = Thread.currentThread().isInterrupted(); // 线程是否中断		System.out.println(isInterrupted); // true		interrupted = Thread.interrupted();		System.out.println(interrupted); // true		isInterrupted = Thread.currentThread().isInterrupted(); // false		System.out.println(isInterrupted); // false				//实际案例!!!		System.out.println("....................................");		Thread t1 = new Thread(new Server());		t1.start();		Thread.sleep(2000);		t1.interrupt(); // 设置t1为中断,如果刚好sleep状态,需要catch块中进行处理。	}		private static class Server implements Runnable {		@Override		public void run() {			// 中断标记为false就一直运行			while(!Thread.currentThread().isInterrupted()){				try {					Thread.sleep(200);				} catch (InterruptedException e1) {					// 如果外部调用interrupt(),而刚好sleep状态,那么此时中断标记变成false。					// 人工再变成true,才可以起到通过while循环中的判断停止线程的作用。					Thread.currentThread().interrupt(); 				}				System.out.println(Thread.currentThread().getName());			}		}	}}

 

 

 

 

 

转载地址:http://ghuni.baihongyu.com/

你可能感兴趣的文章
github简单使用教程
查看>>
如何高效利用GitHub
查看>>
环境分支-git版本管理
查看>>
uni-app 全局变量
查看>>
java 不用递归写tree
查看>>
springboot2 集成Hibernate JPA 用 声明式事物
查看>>
fhs-framework jetcache 缓存维护之自动清除缓存
查看>>
SpringBoot 动态编译 JAVA class 解决 jar in jar 的依赖问题
查看>>
fhs-framework springboot mybatis 解决表关联查询问题的关键方案-翻译服务
查看>>
ZUUL2 使用场景
查看>>
Spring AOP + Redis + 注解实现redis 分布式锁
查看>>
支付宝生活号服务号 用户信息获取 oauth2 登录对接 springboot java
查看>>
CodeForces #196(Div. 2) 337D Book of Evil (树形dp)
查看>>
uva 12260 - Free Goodies (dp,贪心 | 好题)
查看>>
uva-1427 Parade (单调队列优化dp)
查看>>
【设计模式】学习笔记14:状态模式(State)
查看>>
poj 1976 A Mini Locomotive (dp 二维01背包)
查看>>
斯坦福大学机器学习——因子分析(Factor analysis)
查看>>
项目导入时报错:The import javax.servlet.http.HttpServletRequest cannot be resolved
查看>>
linux对于没有写权限的文件如何保存退出vim
查看>>