并发:同时执行多个线程,提高应用程序的效率和资源利用率。java提供包java.util.concurrent来实现并发。java实现并发的2种方式:
1、原子变量:提高性能,且有助于避免数据不一致。java使用包java.util.concurrent.atomic实现原子变量。
1)原子变量的特点:
a)原子变量的所有更改都会立即更新。
b)原子变量的所有更改一定会成功,不会丢失任何数据。
2)原子操作:是作为单个单元执行的操作;在操作期间不能被任何其他操作停止。
3)原子变量java.util.concurrent.atomic包的类有:
a)AtomicInteger
b)AtomicBoolean
c)AtomicIntegerArray
d)AtomicLong
e)AtomicLongArray
4)用法参考代码:
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicDemo {
public static void main(String[] args) {
//声明原子变量
AtomicInteger number=new AtomicInteger(5);
System.out.println("原始值:"+number.get());
//原子操作
number.getAndIncrement();//先获取,再++
System.out.println("原子操作后:"+number.get());
//第一个参数是预期结果,第二个参数是符合预期结果时需要更新的值
number.compareAndSet(6, 66);
System.out.println("更新后的数据:"+number.get());
}
}
运行结果:
原始值:5
原子操作后:6
更新后的数据:66
2、可重入锁:用于线程间互相锁,一个线程可以锁很多次
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockDemo implements Runnable {
final Lock lock = new ReentrantLock();// 声明可重入锁
@Override
public void run() {
do {// 因为不知道tryLock方法执行多少次
try {
// 尝试锁定,可传入等待的最长时间是400毫秒,第二个表示时间单位
if (lock.tryLock(400, TimeUnit.MILLISECONDS)) {
System.out.println(Thread.currentThread().getName()
+ "正在获取锁");
Thread.sleep(1000);
lock.unlock();
System.out.println(Thread.currentThread().getName()
+ "正在释放锁");
break;
} else {
System.out.println("其他线程正在使用锁,需要继续尝试");
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} while (true);
}
public static void main(String[] args) {
ReentrantLockDemo rl = new ReentrantLockDemo();
Thread t1 = new Thread(rl, "线程A");
Thread t2 = new Thread(rl, "线程B");
Thread t3 = new Thread(rl, "线程C");
t1.start();
t2.start();
t3.start();
}
}
3、可重入读写锁,用法参考代码:
import java.util.Random;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ThreadLock extends Thread{
final ReentrantReadWriteLock lock=new ReentrantReadWriteLock();//声明一个读写锁
public void run(){
try {
readData();
Thread.sleep(1000);
writeData();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void readData(){
//读取数据前加锁
lock.readLock().lock();//获取读锁,并获取资源
System.out.println(Thread.currentThread().getName()
+ "正在读取数据");
lock.readLock().unlock();//释放读锁,并获取资源
}
private void writeData(){
lock.writeLock().lock();
Random r=new Random();
int number=r.nextInt(10);
System.out.println(Thread.currentThread().getName()
+ "正在写入数据"+number);
lock.writeLock().unlock();
}
public static void main(String[] args) {
ThreadLock rl = new ThreadLock();
Thread t1 = new Thread(rl, "线程A");
Thread t2 = new Thread(rl, "线程B");
Thread t3 = new Thread(rl, "线程C");
t1.start();
t2.start();
t3.start();
}
}