通过显示定义同步锁对象来实现同步,同步锁使用Lock对象充当ReentrantLock类(可重入锁)实现了Locksynchronized与Lock的对比
Lock是显示锁(手动开启和关闭锁),synchronized是隐式锁,出了作用域自动释放Lock只有代码块锁使用Lock锁,JVM将花费较少的时间来调度线程,性能更好。并且具有更好的扩展性(提供更多的子类)优先使用顺序:Lock>同步代码块>同步方法
class Lock2 implements Runnable{
int ticketNums = 10;
//定义Lock锁
private final ReentrantLock relock = new ReentrantLock();
@Override
public void run() {
while (true){
try{
relock.lock();//加锁
if (ticketNums>0){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"拿到了"+ticketNums--);
}else {
break;
}
}finally {
relock.unlock();//解锁
}
}
读写锁 ReentrantReadWriteLock
public class ReadWrite {
private ReentrantLock ree = new ReentrantLock();
//创建读写锁
private ReentrantReadWriteLock rrl = new ReentrantReadWriteLock();
//获取读锁
private ReentrantReadWriteLock.ReadLock readlock = rrl.readLock();
//获取写锁
private ReentrantReadWriteLock.WriteLock writelock = rrl.writeLock();
private String value;
public String getValue(){
readlock.lock();
try{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"读取"+this.value);
return this.value;
}finally {
readlock.unlock();
}
}
public void setValue(String value){
writelock.lock();
try {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"写入--->"+value);
this.value = value;
}finally {
writelock.unlock();
}
}
}
public class TestReadWrite {
public static void main(String[] args) {
ReadWrite readWrite = new ReadWrite();
//创建线程池
ExecutorService executorService = Executors.newFixedThreadPool(20);
long starttime = System.currentTimeMillis();
//分配2个写任务
for (int i = 0; i < 2; i++) {
executorService.submit(new Runnable() {
@Override
public void run() {
readWrite.setValue("hello world:"+new Random().nextInt(100));
}
});
}
//分配18个读任务
for (int i = 0; i < 20; i++) {
executorService.submit(new Runnable() {
@Override
public void run() {
readWrite.getValue();
}
});
}
executorService.shutdown();
while(!executorService.isTerminated()){
}
long endtime = System.currentTimeMillis();
System.out.println("用时:"+(endtime-starttime));
}
}
线程协作
生产者消费者
//产品
public class Bread {
private int id;
private String productorName;
//容器,缓冲区
public class Contain {
//存放面包的数组
private Bread[] contain = new Bread[6];
//存放面包的位置
private int index=0;
//放面包
public synchronized void input(Bread b){
while (index>5){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
contain[index]=b;
System.out.println(Thread.currentThread().getName()+"生产了"+b.getId()+"");
index++;
this.notifyAll();
}
//取面包
public synchronized void output(){
while (index<=0){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
index--;
Bread b = contain[index];
System.out.println(Thread.currentThread().getName()+"消费了"+b.getId()+"生产者"+b.getProductorName());
contain[index]=null;
this.notifyAll();
}
}
//生产
public class Product implements Runnable{
private Contain con;
public Product(Contain con) {
this.con = con;
}
@Override
public void run() {
for (int i = 0; i < 30; i++) {
con.input(new Bread(i,Thread.currentThread().getName()));
}
}
}
//消费
public Consumer(Contain con) {
this.con = con;
}
@Override
public void run() {
for (int i = 0; i < 30; i++) {
con.output();
}
}
}
public class Test {
public static void main(String[] args) {
Contain contain = new Contain();
Product product = new Product(contain);
Consumer consumer = new Consumer(contain);
new Thread(product,"s").start();
new Thread(product,"c").start();
new Thread(consumer,"h").start();
new Thread(consumer,"l").start();
}
}
线程池
问题
线程是宝贵的内存资源,单个线程约占1M空间,过多分配易造成内存溢出频繁的创建和销毁线程会增加虚拟机回收频率、资源开销,造成程序性能下降 线程池
线程容器,可设定线程分配的数量上限将预先创建的线程对象存入池中,并重用线程池中的线程对象 创建线程池:常用的线程池接口和类(所在包java.util.concurrent)
Executor:线程池的顶级接口ExecutorService:线程池接口,可通过submit(Runnable task)提交任务代码ExecutorService实现类:ScheduledThreadPoolExecutor , ThreadPoolExecutorExecutors工具类:通过此类可以获得一个线程池
public static void main(String[] args) {
//1.创建固定线程个数线程池
ExecutorService executorService = Executors.newFixedThreadPool(4);
//创建缓存线程池
//ExecutorService executorService = Executors.newCachedThreadPool();
//创建单线程池
//ExecutorService executorService1 = Executors.newSingleThreadExecutor();
//创建调度线程池
//ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);
//2.创建任务
Runnable runnable = new Runnable() {
private int ticketNums=10;
@Override
public synchronized void run() {
while (true){
if (ticketNums<=0){
break;
}
System.out.println(Thread.currentThread().getName()+"买了第"+ticketNums--+"票");
}
}
};
//3.提交任务
for (int i = 0; i < 4; i++) {
executorService.submit(runnable);
}
//4.关闭线程池
executorService.shutdown();
}
}
Future接口+Callable+线程池
public class Demo3 {
public static void main(String[] args) throws Exception{
//创建线程池
ExecutorService executorService = Executors.newFixedThreadPool(2);
//提交任务
Future task1 = executorService.submit(new Callable() {
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 1; i <= 50; i++) {
sum += i;
}
System.out.println("1-50计算完毕");
return sum;
}
});
Future task2 = executorService.submit(new Callable() {
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 51; i <= 100; i++) {
sum += i;
}
System.out.println("51-100计算完毕");
return sum;
}
});
//获取结果
int sum = task1.get()+task2.get();
System.out.println(sum);
//关闭线程池
executorService.shutdown();
}
}



