*进程和线程
进程:一个正在进行的程序,比如你电脑中的word、QQ等
线程:简单的理解就是一个进程中的执行事件,比如Eclipse创建一个HelloWorld,main函数就是一个线程,main函数中的代码是顺序执行,那么如果我们想在运行main函数的时候想让他再执行另一段代码的话,那么这就是多线程。
进程中必须至少有一个线程
多个线程之间的执行是独立的互不相干
*线程的创建
在说线程的创建之前我们先说下线程的生命周期
首先在创建一个线程之后他的状态是新生的,调用他的start方法之后改线程状态变为可运行,这边注意start方法调用之后并不是直接进入运行状态,虚拟机在众多可运行状态的线程中挑选一个进入运行状态,到这边线程中执行的事件才开始运行。但是一个线程并不能独占虚拟机,他可能在运行到某个时候进入睡眠/等待/阻塞状态,那么虚拟机将在重新挑选一个线程进入可运行状态,一个线程进入睡眠或者等待状态之后,睡眠时间到或者等待被唤醒之后就会变成可运行状态。当一个线程中所有的事件都执行完毕之后,线程就进入死亡状态。上述差不多就是一个线程的生命周期。
*线程的创建
继承Thread类重新run方法
public static void main(String[] args) {
// TODO Auto-generated method stub
new Thread(){
public void run() {
for(int i =0;i<20;i++){
System.out.println(Thread.currentThread().getName()+" "+i);
}
};
}.start();
}
实现Runnable接口实现run方法
public static void main(String[] args) {
// TODO Auto-generated method stub
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
for(int i =0;i<20;i++){
System.out.println(Thread.currentThread().getName()+" "+i);
}
}
}).start();
}
写在同一个类中运行
public static void main(String[] args) {
// TODO Auto-generated method stub
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
for(int j =10;j<20;j++){
System.out.println(Thread.currentThread().getName()+" "+j);
}
}
}){
public void run() {
for(int i =0;i<10;i++){
System.out.println(Thread.currentThread().getName()+" "+i);
}
};
}.start();
看下输出:
*线程的安全与同步
当多个线程操作同一个数据并且操作的时间较长的时候就容易出现数据错误的问题,看下代码
public class Blog1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
data d=new data();
Thread t1=new Thread(d);
Thread t2=new Thread(d);
Thread t3=new Thread(d);
Thread t4=new Thread(d);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class data implements Runnable {
private int num=50;
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
if(num>0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("当前线程为:"+Thread.currentThread().getName()+"操作时数据为:"+num);
num--;
}
}
}
}
开启4个线程对data类中的num变量进行操作,一直做减法,在判断是否大于0之后让线程睡眠100毫秒模拟操作一个很长的事件,看下输出
Thread-3和Thread-0操作时数据都为2并且最后还出现了负数的情况,那是因为当多个线程下if语句里面进行睡眠等待,当执行线程执行num--之后,等待的线程醒了,继续往下执行,就出现了负数的情况。导致数据错误,这段代码原本是想当num大于0时才进行打印。
所以上述代码中应该保证if判断语句、输出语句和num--这块代码必须同步即一个线程在操作的时候其他线程不允许操作,那就要用到同步代码块
同步代码块的关键字为synchronized
格式为synchronized(对象){
需要同步的语句;
}
所以我们将上面的代码修改一下
public class Blog1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
data d=new data();
Thread t1=new Thread(d);
Thread t2=new Thread(d);
Thread t3=new Thread(d);
Thread t4=new Thread(d);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class data implements Runnable {
private int num=50;
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
synchronized(this){
if(num>0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("当前线程为:"+Thread.currentThread().getName()+"操作时数据为:"+num);
num--;
}
}
}
}
}
加上同步语句,看下输出
数据就不会出现0或者负数了
synchronized同步语句相当于加了一把锁,当多个线程运行到这的时候都会去判断synchronized的锁是不是被其他线程占用了,如果被其他线程占有了就等待,直到该锁被其他线程释放之后能进入同步代码块。
锁
package com.ccl.test;
public class DeadLock1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
data1 d1=new data1(true);
data1 d2=new data1(false);
Thread t1=new Thread(d1);
Thread t2=new Thread(d2);
t1.start();
t2.start();
}
}
class data1 implements Runnable{
private boolean flag;
public data1(boolean flag){
this.flag=flag;
}
@Override
public void run() {
// TODO Auto-generated method stub
if(flag){
while(true){
synchronized(Mylock.obj1){
System.out.println(Thread.currentThread().getName()+" get obj1 lock");
synchronized(Mylock.obj2){
System.out.println(Thread.currentThread().getName()+" get obj2 lock");
}
}
}
}else{
while(true){
synchronized(Mylock.obj2){
System.out.println(Thread.currentThread().getName()+" get obj2 lock");
synchronized(Mylock.obj1){
System.out.println(Thread.currentThread().getName()+" get obj1 lock");
}
}
}
}
}
}
class Mylock {
public static final Object obj1=new Object();
public static final Object obj2=new Object();
}
package com.ccl.test;
public class MakerBuyer {
public static void main(String[] args) {
// TODO Auto-generated method stub
Goods goods=new Goods("包子");
Maker maker=new Maker(goods);
Buyer buyer=new Buyer(goods);
Thread t0=new Thread(maker);
Thread t1=new Thread(buyer);
t0.start();
t1.start();
}
}
//商品类
class Goods{
private String name; //商品名称
private int count=1; //商品个数
private boolean isNoMake=false; //是否不能制造商品
public Goods(String name){
this.name=name;
}
public synchronized void makeGoods(){
if(isNoMake){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
name="商品"+count++;
System.out.println("当前线程:"+Thread.currentThread().getName()+"====制造了"+name);
isNoMake=true;
notify();
}
public synchronized void buyGoods(){
if(!isNoMake){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("当前线程:"+Thread.currentThread().getName()+"====把"+name+"=============买走了");
isNoMake=false;
notify();
}
}
class Maker implements Runnable{
Goods g;
public Maker(Goods g){
this.g=g;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
g.makeGoods();
}
}
}
class Buyer implements Runnable{
Goods g;
public Buyer(Goods g){
this.g=g;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
g.buyGoods();
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Goods goods=new Goods("包子");
Maker maker=new Maker(goods);
Maker maker1=new Maker(goods);
Buyer buyer=new Buyer(goods);
Buyer buyer1=new Buyer(goods);
Thread t0=new Thread(maker);
Thread t1=new Thread(maker1);
Thread t2=new Thread(buyer);
Thread t3=new Thread(buyer1);
t0.start();
t1.start();
t2.start();
t3.start();
}
package com.ccl.test;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class MakerBuyer {
public static void main(String[] args) {
// TODO Auto-generated method stub
Goods goods=new Goods("包子");
Maker maker=new Maker(goods);
Maker maker1=new Maker(goods);
Buyer buyer=new Buyer(goods);
Buyer buyer1=new Buyer(goods);
Thread t0=new Thread(maker);
Thread t1=new Thread(maker1);
Thread t2=new Thread(buyer);
Thread t3=new Thread(buyer1);
t0.start();
t1.start();
t2.start();
t3.start();
}
}
//商品类
class Goods{
private String name; //商品名称
private int count=1; //商品个数
private boolean isNoMake=false; //是否不能制造商品
private Lock lock=new ReentrantLock();
Condition makerCondition=lock.newCondition();
Condition buyerCondition=lock.newCondition();
public Goods(String name){
this.name=name;
}
public void makeGoods(){
lock.lock();
try{
while(isNoMake){
try {
makerCondition.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
name="商品"+count++;
System.out.println("当前线程:"+Thread.currentThread().getName()+"====制造了"+name);
isNoMake=true;
buyerCondition.signal();
}finally{
lock.unlock();
}
}
public void buyGoods(){
lock.lock();
try{
while(!isNoMake){
try {
buyerCondition.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("当前线程:"+Thread.currentThread().getName()+"====把"+name+"=============买走了");
isNoMake=false;
makerCondition.signal();
}finally{
lock.unlock();
}
}
}
class Maker implements Runnable{
Goods g;
public Maker(Goods g){
this.g=g;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
g.makeGoods();
}
}
}
class Buyer implements Runnable{
Goods g;
public Buyer(Goods g){
this.g=g;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
g.buyGoods();
}
}
}
package com.ccl.test;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ConditionAPIDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
BounderBuffer bounderBuffer=new BounderBuffer();
Maker1 maker=new Maker1(bounderBuffer);
Maker1 maker1=new Maker1(bounderBuffer);
Buyer1 buyer=new Buyer1(bounderBuffer);
Buyer1 buyer1=new Buyer1(bounderBuffer);
Thread t0=new Thread(maker);
Thread t1=new Thread(maker1);
Thread t2=new Thread(buyer);
Thread t3=new Thread(buyer1);
t0.start();
t1.start();
t2.start();
t3.start();
}
}
class BounderBuffer{
final Lock lock=new ReentrantLock();//定义锁
final Condition notFull=lock.newCondition();
final Condition notEmpty=lock.newCondition();
final Object []items=new Object[100];
int putptr,takeptr,count;
public void makeGoods(Object goodsName){
lock.lock();
try{
while(count==items.length){
notFull.await();
}
items[putptr]=goodsName.toString()+putptr;
System.out.println("当前线程 :"+Thread.currentThread().getName()+"===生产了"+goodsName+" "+putptr );
if(++putptr==items.length) putptr=0;
count++;
notEmpty.signal();
}catch(Exception e){
//处理语句
}finally{
lock.unlock();
}
}
public void buyGoods(){
lock.lock();
try{
while(count==0){
notEmpty.await();
}
Object goodsName=items[takeptr];
System.out.println("当前线程 :"+Thread.currentThread().getName()+"===消费了商品========"+goodsName);
if(++takeptr==items.length) takeptr=0;
count--;
notFull.signal();
}catch(Exception e){
//处理语句
}finally{
lock.unlock();
}
}
}
class Maker1 implements Runnable{
BounderBuffer bounderBuffer;
public Maker1(BounderBuffer bounderBuffer){
this.bounderBuffer=bounderBuffer;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
bounderBuffer.makeGoods("包子");
}
}
}
class Buyer1 implements Runnable{
BounderBuffer bounderBuffer;
public Buyer1(BounderBuffer bounderBuffer){
this.bounderBuffer=bounderBuffer;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
bounderBuffer.buyGoods();
}
}
}
线程池
package com.ccl.test;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class ThreadPoolTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
//固定的线程池
ExecutorService threadPool=Executors.newFixedThreadPool(3);
//缓存的线程池,几个任务就生成几个线程
//ExecutorService threadPool=Executors.newCachedThreadPool();
//单线程线程池 如果线程死了自动生成一个替补
//ExecutorService threadPool=Executors.newSingleThreadExecutor();
for(int i =1 ;i<=10;i++){
final int task=i;
threadPool.execute(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
for(int j=1;j<=3;j++){
try {
Thread.sleep(30);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() +"=====正在生产商品"+task+"的第"+j+"个步骤");
}
}
});
}
}
}
运行结果:
package com.ccl.test;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class CallableAndFutureTest {
public static void main(String[] args) {
System.out.println("工人们正在努力生产商品中。。。");
//创建线程池3个线程
ExecutorService threadPool=Executors.newFixedThreadPool(3);
CompletionService<Map<String,String >> completionService=new ExecutorCompletionService<Map<String,String >>(threadPool);
//生产10个商品
for(int i=1;i<=10;i++){
final int task=i;
completionService.submit(new Callable<Map<String,String >>() {
@Override
public Map<String,String > call() throws Exception {
// TODO Auto-generated method stub
Map<String,String> map=new HashMap<String, String>();
//生产每个商品有3个步骤
for(int j=1;j<=3;j++){
try {
Thread.sleep(30);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() +"=====正在生产商品"+task+"的第"+j+"个步骤");
}
//商品生产结束之后存入map
map.put("result",Thread.currentThread().getName()+"===生产了商品"+task);
return map;
}
});
}
//获取数据,获取十次数据,若是没有返回数据则等待
for (int i=1;i<=10;i++){
try {
Map<String , String > resultMap=completionService.take().get();
System.out.println(resultMap.get("result"));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
package com.ccl.test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
public class SemaphoreTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
//定义一个缓存线程池
ExecutorService threadPool=Executors.newCachedThreadPool();
//定义semaphore信号灯
final Semaphore semaphore=new Semaphore(3);
//开启十个任务
for(int i=0;i<10;i++){
threadPool.execute(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
//判断是否还有信号灯可以获取,如果没有则等待
Thread.sleep((long) (Math.random()*10000));
semaphore.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("工人:"+Thread.currentThread().getName()+"进入操作间,当前还剩"+(semaphore.availablePermits())+"间操作间");
try {
//模拟工人在操作间进行操作要花费时间
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("工人:"+Thread.currentThread().getName()+"操作完毕,即将离开操作间");
//释放信号灯
semaphore.release();
System.out.println("工人:"+Thread.currentThread().getName()+"已经离开操作间,当前还剩"+(semaphore.availablePermits())+"间操作间");
}
});
}
}
}
package com.ccl.test;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CyclicBarrierTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
ExecutorService threadPool=Executors.newCachedThreadPool();
final CyclicBarrier cyclicBarrier=new CyclicBarrier(10);
//等待10个工人同时到达
for(int i=0;i<10;i++){
threadPool.execute(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
//模拟十个工人到达时间不一致
Thread.sleep((long) (Math.random()*10000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("工人:"+Thread.currentThread().getName()+"已准备好,还需要"+(10-cyclicBarrier.getNumberWaiting()-1)+"工人可以开始生产");
try {
cyclicBarrier.await();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("工人:"+Thread.currentThread().getName()+"正在生产商品");
}
});
}
}
}
运行结果:
package com.ccl.test;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CountDownLatchTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
ExecutorService threadPool = Executors.newCachedThreadPool();
//定义裁判计数器
final CountDownLatch countDownLatch1=new CountDownLatch(1);
//定义有几个工人在比赛
final CountDownLatch countDownLatch2=new CountDownLatch(3);
//模拟3个工人在比赛
for(int i=0;i<3;i++){
threadPool.execute(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("工人:"+Thread.currentThread().getName()+"已准备就绪");
try {
//等待裁判计时器为0时继续往下走
countDownLatch1.await();
//模拟工人生产商品时需要的时间
System.out.println("工人"+Thread.currentThread().getName()+"开始生产");
Thread.sleep((long) (Math.random()*10000));
System.out.println("工人"+Thread.currentThread().getName()+"已生产完毕");
//将剩余人数计数器减1
countDownLatch2.countDown();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
//模拟裁判开始比赛和结束比赛
try{
Thread.sleep((long) (Math.random()*10000));
System.out.println("各就各位,预备。。。。。。");
countDownLatch1.countDown();
System.out.println("比赛开始");
countDownLatch2.await();
System.out.println("全部工人已完成商品,比赛结束");
}catch(Exception e){
e.printStackTrace();
}
}
}
package com.ccl.test;
import java.util.concurrent.Exchanger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExchangerTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
ExecutorService threadPool=Executors.newCachedThreadPool();
final Exchanger exchanger=new Exchanger();
threadPool.execute(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
String data1="零件1";
System.out.println("工人:"+Thread.currentThread().getName()+"已到达,正在等待拿零件1换取零件2");
try {
Thread.sleep((long) (Math.random()*10000));
String data2=(String) exchanger.exchange(data1);
System.out.println("工人:"+Thread.currentThread().getName()+"已经换取"+data2);
} catch ( Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
threadPool.execute(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
String data1="零件2";
System.out.println("工人:"+Thread.currentThread().getName()+"已到达,正在等待拿零件2换取零件1");
try {
Thread.sleep((long) (Math.random()*10000));
String data2=(String) exchanger.exchange(data1);
System.out.println("工人:"+Thread.currentThread().getName()+"已经换取"+data2);
} catch ( Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
运行结果: