package com.thread.demo01;
public class MyThread extends Thread {
public MyThread() {
}
public MyThread(String name) {
super(name);
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
//方式一: this.getId()获取线程Id,this.getName()获取线程名称
//System.out.println("线程id: " + this.getId() + " 线程名称: " + this.getName() + " 子线程:......" +i);
//方式二(推荐): Thread.currentThread() 获取当前线程
System.out.println("线程id: " + Thread.currentThread().getId() + " 线程名称: " + Thread.currentThread().getName() + " 子线程:......" + i);
}
}
}
启动多个线程
package com.thread.demo01;
public class TestThread {
public static void main(String[] args) {
//1. 创建线程对象
MyThread myThread = new MyThread("我的子线程1");
//2. 启动线程,不能用run()方法
//myThread.setName("我的子线程1"); //启动线程前设置线程名称
myThread.start();
System.out.println(myThread.getId());
MyThread myThread1 = new MyThread("我的子线程2);
//myThread1.setName("我的子线程2"); //启动线程前设置线程名称
myThread1.start();
System.out.println(myThread1.getId());
//主线程执行
for (int i = 0; i < 50; i++) {
System.out.println("主线程:......" + i);
}
}
}
public class SellTicket extends Thread{
public SellTicket() {
}
public SellTicket(String name){
super(name);
}
private int ticket = 100;//票
@Override
public void run() {
while (ticket > 0) {
System.out.println(Thread.currentThread().getName() + "卖的第" + (101 - ticket) + "张票");
ticket--;
}
}
}
public class TestTicket {
public static void main(String[] args) {
//1. 创建四个卖票窗口
SellTicket st1 = new SellTicket("窗口一");
SellTicket st2 = new SellTicket("窗口二");
SellTicket st3 = new SellTicket("窗口三");
SellTicket st4 = new SellTicket("窗口四");
//2. 开启多线程
st1.start();
st2.start();
st3.start();
st4.start();
}
}
Thread的构造方法,可传入Runnable target, String name ,即Runnable接口类型的对象和字符串类型的名称
private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc,
boolean inheritThreadLocals)
public class MyRunnable implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + "子线程......" + i);
}
}
}
public class TestRunnable {
public static void main(String[] args) {
//创建MyRunnable对象, 表示线程要执行的功能
MyRunnable runnable = new MyRunnable();
//2. 创建线程对象
Thread thread = new Thread(runnable, "我的线程一");
Thread thread1 = new Thread(runnable, "我的线程二");
//3. 启动多线程
thread.start();
thread1.start();
for (int i = 0; i < 50; i++) {
System.out.println("主线程" + i);
}
}
}
方式二优化: 使用匿名内部类
public class TestRunnable1 {
public static void main(String[] args) {
//1. 创建Runnable对象, 以及使用匿名内部类
Runnable runnable = new Runnable() {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + "子线程......" + i);
}
}
};
//2. 创建线程对象
Thread thread = new Thread(runnable, "我的线程1");
Thread thread1 = new Thread(runnable, "我的线程2");
//3. 启动多线程
thread.start();
thread1.start();
for (int i = 0; i < 50; i++) {
System.out.println("主线程" + i);
}
}
}
public class Ticket implements Runnable{
private int ticket = 100;
@Override
public void run() {
while (ticket > 0){
System.out.println(Thread.currentThread().getName() + "售出第" + (101-ticket) + "张票");
ticket--;
}
}
}
public class TestTicket {
public static void main(String[] args) {
Ticket ticket = new Ticket();
Thread wd1 = new Thread(ticket, "窗口一: ");
Thread wd2 = new Thread(ticket, "窗口二: ");
Thread wd3 = new Thread(ticket, "窗口三: ");
Thread wd4 = new Thread(ticket, "窗口四: ");
wd1.start();
wd2.start();
wd3.start();
wd4.start();
}
}
public class BankCard {//创建银行卡类
private double money;//余额
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
}
public class AddMoney implements Runnable{//创建存钱类, 实现Runnable接口
private BankCard card;
public AddMoney(BankCard card) {
this.card = card;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
card.setMoney(card.getMoney() + 1000);
System.out.println(Thread.currentThread().getName() + "存的第" + (i+1) + "笔钱,金额为1000元, 现卡上余额: " + card.getMoney() + "元");
}
}
}
public class SubMoney implements Runnable{//创建取钱类, 实现Runnable接口
private BankCard card;
public SubMoney(BankCard card) {
this.card = card;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
if (card.getMoney() >= 1000){
card.setMoney(card.getMoney() - 1000);
System.out.println(Thread.currentThread().getName() + "取了第" + (i+1) + "笔钱,金额为1000元, 现卡上余额: " + card.getMoney() + "元");
}else{
System.out.println("余额不足...");
i--;
}
}
}
}
public class TestBankCard {
public static void main(String[] args) {
//1. 创建银行卡对象
BankCard card = new BankCard();
//2. 创建存钱对象
AddMoney addMoney = new AddMoney(card);
//3. 创建取钱对象
SubMoney subMoney = new SubMoney(card);
//4. 创建两个线程
Thread boy = new Thread(addMoney, "男孩");
Thread girl = new Thread(subMoney, "女孩");
//5. 开启线程
boy.start();
girl.start();
}
}
public class SleepThread extends Thread{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "--------------" + i);
try {
SleepThread.sleep(2000);//睡眠两秒钟
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class TestSleep {
public static void main(String[] args) {
SleepThread s1 = new SleepThread();
SleepThread s2 = new SleepThread();
s1.start();
s2.start();
}
}
public class YieldThread extends Thread{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "-------------" + i);
//放弃CPU
YieldThread.yield();
}
}
}
public class TestYield {
public static void main(String[] args) {
YieldThread y1 = new YieldThread();
YieldThread y2 = new YieldThread();
y1.start();
y2.start();
}
}
public class JoinThread extends Thread{
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName() + "子线程------------" + i);
try {
JoinThread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class TestJoin {
public static void main(String[] args) {
JoinThread j1 = new JoinThread();
j1.start();
try {
j1.join();//加入到当前线程main, 并阻塞当前线程main, 直到加入的线程j1执行完毕
} catch (InterruptedException e) {
e.printStackTrace();
}
//主线程
for (int i = 0; i < 30; i++) {
System.out.println(Thread.currentThread().getName() + "主线程: " + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class PriorityThread extends Thread{
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName() + "子线程:------ " + i);
}
}
}
public class TestPriority {
public static void main(String[] args) {
PriorityThread p1 = new PriorityThread();
p1.setName("p1");
PriorityThread p2 = new PriorityThread();
p2.setName("p2");
PriorityThread p3 = new PriorityThread();
p3.setName("p3");
p1.start();
p2.start();
p3.start();
p1.setPriority(1);//优先级最低
p2.setPriority(3);
p3.setPriority(10);//优先级最高
for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName() + "主线程:------ " + i);
}
}
}
public class DaemonThread extends Thread{
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("子线程: " + Thread.currentThread().getName() + "-----------" + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class TestDaemon {
public static void main(String[] args) {
//1. 创建线程(默认为前台线程)
DaemonThread d1 = new DaemonThread();
//2. 设置为守护线程(后台线程) 当主线程执行完毕后,守护线程(后台线程)会自动结束
d1.setDaemon(true);
d1.start();
for (int i = 0; i < 10; i++) {
System.out.println("主线程: " + Thread.currentThread().getName() + "-------" + i);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
同步代码块:
synchronized(临界资源对象){ //对临界资源对象加锁
? //代码(原子操作)
}
注: 每个对象都有一个互斥锁标记, 用来分配给线程的. 只有拥有对象互斥锁标记的线程, 才能进入对该对象加锁的同步代码块.
线程退出同步代码块时, 会释放相应的互斥锁标记
import java.util.Arrays;
public class ThreadSafe {
private static int index = 0;
public static void main(String[] args) throws InterruptedException {
//1. 创建数组
String[] s = new String[5];
//2. 创建两个操作
Runnable runnableA = new Runnable() {
@Override
public void run() {
//同步代码块
synchronized (s){
s[index] = "hello";
index++;
}
}
};
Runnable runnableB = new Runnable() {
@Override
public void run() {
//同步代码块
synchronized (s){
s[index] = "world";
index++;
}
}
};
//3. 创建两个线程
Thread thread1 = new Thread(runnableA, "A");
Thread thread2 = new Thread(runnableB, "B");
//4. 启动
thread1.start();
thread2.start();
//5. 加入线程
thread1.join();
thread2.join();
System.out.println(Arrays.toString(s));
}
}
实现四个窗口共同卖票100张, 不能出现四个窗口同时卖出一张票的情况
public class Ticket implements Runnable{
private int ticket = 100;//票
//创建锁
//private Object obj = new Object();
@Override
public void run() {
while (true){
synchronized (this){//this---当前对象,这里放入obj和this都可以
if (ticket <= 0){
break;
}
System.out.println(Thread.currentThread().getName() + "卖的第" + (101-ticket) + "张票");
ticket--;
}
}
}
}
public class TestSafeTicket {
public static void main(String[] args) {
//1. 创建票对象
Ticket ticket = new Ticket();
//2. 创建四个线程对象
Thread win1 = new Thread(ticket, "窗口一");
Thread win2 = new Thread(ticket, "窗口二");
Thread win3 = new Thread(ticket, "窗口三");
Thread win4 = new Thread(ticket, "窗口四");
//3. 启动
win1.start();
win2.start();
win3.start();
win4.start();
}
}
两人用同一张银行卡,一人存钱,另一人取钱, 不能出现存钱后卡上没钱或卡上没钱还能取出的情况
public class BankCard {
private double money;//余额
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
}
public class TestBank {
public static void main(String[] args) {
//1. 创建银行卡对象
BankCard bankCard = new BankCard();
//2. 创建存钱取钱操作
Runnable addMoney = new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
synchronized (bankCard){
bankCard.setMoney(bankCard.getMoney() + 1000);
System.out.println(Thread.currentThread().getName() + "第" + i + "次存了1000元" + "现卡上余额: " + bankCard.getMoney());
}
}
}
};
Runnable subMoney = new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
synchronized (bankCard){
if (bankCard.getMoney() >= 1000){
bankCard.setMoney(bankCard.getMoney()-1000);
System.out.println(Thread.currentThread().getName() + "第" + i + "次取了1000元" + "现卡上余额: " + bankCard.getMoney());
}else{
System.out.println("余额不足...");
i--;
}
}
}
}
};
//3. 创建两个线程
Thread boy = new Thread(addMoney, "jack");
Thread girl = new Thread(subMoney, "rose");
boy.start();
girl.start();
}
}
同步方法:
synchronized 返回值类型 方法名称(形参列表0) {//对当前对象(this)加锁
? //代码(原子操作)
}
注:
? 只有拥有对象互斥锁标记的线程, 才能进入对该对象加锁的同步 方法中.
? 线程退出同步方法时, 会释放相应的互斥锁标记
public class Ticket1 implements Runnable{
private int ticket1 = 100;
@Override
public void run() {
while (true){
if (!sell()){
break;
}
}
}
public synchronized boolean sell(){//锁是this 代表当前对象ticket1, 如果是静态方法, 锁则是类Ticket1.class
if (ticket1 > 0){
System.out.println(Thread.currentThread().getName() + "卖的第" + (101-ticket1) + "张票");
ticket1--;
}
return true;
}
}
public class TestSafeTicket1 {
public static void main(String[] args) {
//1. 创建票对象
Ticket1 ticket1 = new Ticket1();
Thread w1 = new Thread(ticket1, "窗口1");
Thread w2 = new Thread(ticket1, "窗口2");
Thread w3 = new Thread(ticket1, "窗口3");
Thread w4 = new Thread(ticket1, "窗口4");
w1.start();
w2.start();
w3.start();
w4.start();
}
}
public class MyLock {
//两个锁: 代表两根筷子,同时拿到这两根筷子才能吃饭
public static Object lock1 = new Object();
public static Object lock2 = new Object();
}
public class Boy extends Thread{
@Override
public void run() {
synchronized (MyLock.lock1){
System.out.println("男孩拿到了筷子A");
synchronized (MyLock.lock2){
System.out.println("男孩拿到了筷子B");
System.out.println("男孩可以吃饭了");
}
}
}
}
public class Girl extends Thread{
@Override
public void run() {
synchronized (MyLock.lock2){
System.out.println("女孩拿到了筷子B");
synchronized (MyLock.lock1){
System.out.println("女孩拿到了筷子A");
System.out.println("女孩可以吃饭了");
}
}
}
}
public class TestDeadLock {
public static void main(String[] args) {
//1. 创建两个线程对象男孩, 女孩
Boy boy = new Boy();
Girl girl = new Girl();
//2. 女孩线程启动
girl.start();
//3. 休息0.5秒钟(如果他们两个同时启动就会造成死锁)
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
//4. 最后启动男孩线程
boy.start();
}
}
等待
通知
多存多取问题分析: 线程被重新唤醒后没有对标记flag进行判断
全部等待问题分析: 唤醒出现问题. notify 只能随机唤醒一个线程
银行卡类
public class BankCard {
//余额
private double money;
//标记
private boolean flag = false;//true 表示有钱可以取不能存, false表示没钱可以存不能取
//存钱
public synchronized void deposit(double m){//this
while (flag){//有钱
try {
this.wait();//进入等待队列 调用wait()方法的对象一定是锁,this代表锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
money = money + m;
System.out.println(Thread.currentThread().getName() + "存了" + m + "元, 当前余额为: " + money);
//修改标记
flag = true;
//唤醒取钱线程
this.notifyAll();
}
//取钱
public synchronized void draw(double m){//this
while (!flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
money = money - m;
System.out.println(Thread.currentThread().getName() + "取了" + m + "元, 当前余额为: " + money);
//修改标记
flag = false;
//唤醒存钱线程
this.notifyAll();
}
}
存钱
public class Deposit implements Runnable{
private BankCard bankCard;
public Deposit(BankCard bankCard){
this.bankCard = bankCard;
}
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
bankCard.deposit(1000);
}
}
}
取钱
public class Draw implements Runnable{
private BankCard bankCard;
public Draw(BankCard bankCard){
this.bankCard = bankCard;
}
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
bankCard.draw(1000);
}
}
}
若干个生产者在生产产品, 这些产品将提供给若干个消费者去消费, 为了使生产者和消费者能并发执行, 在两者之间设置一个能存储多个产品的缓冲区, 生产者将生产的产品放入缓冲区中, 消费者从缓冲区中取走产品进行消费, 显然生产者和消费者之间必须保持同步, 即不允许消费者到一个空的缓冲区中取产品, 也不允许生产者向一个满的缓冲区中放入产品
面包类
public class Bread {
private int id;//产品id
private String productName;//产家名称
public Bread(int id, String productName) {
this.id = id;
this.productName = productName;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
}
存放面包的容器
public class BreadCon {
//存放面包的数组
private Bread[] cons = new Bread[6];
//存放面包的位置
private int index = 0;
//存放面包
public synchronized void input(Bread b){ // 锁this
//判断容器有没有满
while (index >= 6){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
cons[index] = b;
System.out.println(Thread.currentThread().getName() + "生产了" + b.getId() + "号产品");
index++;
//唤醒
this.notifyAll();
}
//取出面包
public synchronized void output(){ // 锁this
while (index <= 0){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
index--;
Bread b = cons[index];
System.out.println(Thread.currentThread().getName() + "消费了" + b.getProductName() + "生产的" + b.getId() + "号产品");
cons[index] = null;
//唤醒
this.notifyAll();
}
}
生产类
public class Product implements Runnable{
private BreadCon con;
public Product(BreadCon con) {
this.con = con;
}
@Override
public void run() {
for (int i = 0; i < 30; i++) {
con.input(new Bread(i, Thread.currentThread().getName()));
}
}
}
消费类
public class Consume implements Runnable{
private BreadCon con;
public Consume(BreadCon 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) {
//容器
BreadCon con = new BreadCon();
//生产和消费
Product product = new Product(con);
Consume consume = new Consume(con);
//创建线程对象
Thread p1 = new Thread(product, "1号厂家");
Thread c1 = new Thread(consume, "1号消费者");
Thread p2 = new Thread(product, "2号厂家");
Thread c2 = new Thread(consume, "2号消费者");
//启动线程
p1.start();
c1.start();
p2.start();
c2.start();
}
}
public class Demo01 {
public static void main(String[] args) {
//1. 创建线程池
//1.1 创建固定线程个数的线程池
//ExecutorService es = Executors.newFixedThreadPool(4);
//1.2 创建缓存线程池, 线程个数由任务个数决定
ExecutorService es = Executors.newCachedThreadPool();
//1.3 创建单线程池
//Executors.newSingleThreadExecutor();
//1.4 创建调度线程池
//Executors.newScheduledThreadPool(3);
//2. 创建任务
Runnable runnable = new Runnable() {
private int ticket = 100;
@Override
public void run() {
while (true){
if (ticket <= 0){
break;
}
System.out.println(Thread.currentThread().getName() + "卖的第" + (101-ticket) + "张票");
ticket--;
}
}
};
//3. 提交任务
for (int i = 0; i < 4; i++) {
es.submit(runnable);
}
//4. 关闭线程池
es.shutdown();//等待所有任务执行完毕后才会结束,关闭线程池
//es.shutdownNow();//试图停止所有正在执行的活动任务, 暂停处理正在等待的任务,并返回等待执行的任务列表
}
}
public interface Callable
? public V call() throws Exception;
}
使用Callable实现1-100的和
public class Demo02 {
public static void main(String[] args) throws Exception{
//功能需求: 使用Callable实现1-100的和
//1. 创建Callable对象
Callable<Integer> callable = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
System.out.println(Thread.currentThread().getName() + "开始计算: ");
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
return sum;
}
};
//2. 把Callable对象转成可执行的任务
FutureTask<Integer> task = new FutureTask<>(callable);
//3. 创建线程
Thread thread = new Thread(task);
//4. 启动线程
thread.start();
//5. 获取结果(等待call方法执行完毕,才会返回)
Integer sum = task.get();
System.out.println("结果是: " + sum);
}
}
使用线程池计算1-100的和
public class Demo03 {
public static void main(String[] args) throws Exception{
//1. 创建线程池
ExecutorService es = Executors.newFixedThreadPool(1);
//2. 提交任务Future:表示将要执行完任务的结果
Future<Integer> future = es.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
System.out.println(Thread.currentThread().getName() + "开始计算: ");
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
Thread.sleep(10);
}
return sum;
}
});
//3. 获取任务结果,等待任务执行完毕才会返回
System.out.println(future.get());
//4. 关闭线程池
es.shutdown();
}
}
public class Demo04 {
public static void main(String[] args) throws Exception{
//1. 创建线程池
ExecutorService es = Executors.newFixedThreadPool(2);
//2. 提交任务
Future<Integer> future1 = es.submit(new Callable<Integer>() {
@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<Integer> future2 = es.submit(new Callable<Integer>() {
@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;
}
});
//3. 获取结果
int sum = future1.get() + future2.get();
System.out.println("结果是: " + sum);
//4. 关闭线程池
es.shutdown();
}
}
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class MyList {
private Lock lock = new ReentrantLock();
private String[] str = {"A", "B", "", "", ""};
private int count = 2;
public void add(String value){
lock.lock();
try{
str[count] = value;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
count++;
} finally {
lock.unlock();
}
}
public String[] getStr(){
return str;
}
}
public class TestMyList {
public static void main(String[] args) throws Exception{
MyList list = new MyList();
Runnable runnable1 = new Runnable() {
@Override
public void run() {
list.add("hello");
}
};
Runnable runnable2 = new Runnable() {
@Override
public void run() {
list.add("world");
}
};
Thread t1 = new Thread(runnable1);
Thread t2 = new Thread(runnable2);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(Arrays.toString(list.getStr()));
}
}
使用重入锁实现4个窗口共同卖100张票
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Ticket implements Runnable{
private int ticket = 100;
private Lock lock = new ReentrantLock();
@Override
public void run() {
while (true){
lock.lock();
try {
if (ticket <= 0){
break;
}
System.out.println(Thread.currentThread().getName() + "卖的第" + (101-ticket) + "张票");
ticket--;
} finally {
lock.unlock();
}
}
}
}
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestTicket {
public static void main(String[] args) {
//1. 创建票对象
Ticket ticket = new Ticket();
//2. 创建线程池对象
ExecutorService es = Executors.newFixedThreadPool(4);
//3. 提交任务
for (int i = 0; i < 4; i++) {
es.submit(ticket);
}
//4. 关闭线程池
es.shutdown();
}
}
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
public class ReadWriteLock {
//创建读写锁
private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
//获取读锁
private ReadLock readLock = rwl.readLock();
//获取写锁
private WriteLock writeLock = rwl.writeLock();
private String value;
//读取
public String getValue(){
//使用读锁上锁
readLock.lock();
try {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("读取: " + 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();
}
this.value = value;
System.out.println("写入: " + value);
} finally {
writeLock.unlock();
}
}
}
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestReadWriteLock {
public static void main(String[] args) {
//1. 创建读写锁对象
ReadWriteLock rwl = new ReadWriteLock();
//2. 创建线程池
ExecutorService es = Executors.newFixedThreadPool(20);
//3. 创建写任务
Runnable write = new Runnable() {
@Override
public void run() {
rwl.setValue("张三: " + new Random().nextInt(100));
}
};
//4. 创建读任务
Runnable read = new Runnable() {
@Override
public void run() {
rwl.getValue();
}
};
Long start = System.currentTimeMillis();//获取系统此刻时间(开始)
//5. 分配2个线程来 写任务
for (int i = 0; i < 2; i++) {
es.submit(write);
}
//6. 分配18个线程来 读任务
for (int i = 0; i < 18; i++) {
es.submit(read);
}
//7. 关闭
es.shutdown();
while (!es.isTerminated()) {//空转
}
Long end = System.currentTimeMillis();//获取系统此刻时间(结束)
System.out.println("用时: " + (end - start));//3007 如果使用用互斥锁时间为: 20048
}
}
public class Demo02 {
public static void main(String[] args) {
//1. 创建集合
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
//2. 使用多线程操作
ExecutorService es = Executors.newFixedThreadPool(5);
//3. 提交任务
for (int i = 0; i < 5; i++) {
es.submit(new Runnable() {
@Override
public void run() {
for (int j = 0; j < 10; j++) {
list.add(Thread.currentThread().getName() + "---" + new Random().nextInt(1000));
}
}
});
}
//4. 关闭线程池
es.shutdown();
while (!es.isTerminated()){}
//5. 打印结果
System.out.println("元素个数: " + list.size());
for (String s : list) {
System.out.println(s);
}
}
}
public class Demo04 {
public static void main(String[] args) {
//1. 创建队列
Queue<String> queue = new LinkedList<>();// LinkedList是线程不安全的集合,不能使用多线程
//2. 入队
queue.offer("香蕉");
queue.offer("苹果");
queue.offer("橘子");
queue.offer("橙子");
System.out.println("入队完毕, 元素个数: " + queue.size());
System.out.println(queue.peek());//获取队列第一个元素但不移除
System.out.println("----------------------");
//3. 出队
int size = queue.size();
for (int i = 0; i < size; i++) {
System.out.println(queue.poll());//获得第一个元素并移除
}
System.out.println("出队完毕, 元素个数: " + queue.size());
}
}
public class Demo05 {
public static void main(String[] args) throws Exception{
//1. 创建线程安全集合
ConcurrentLinkedQueue<Integer> queue = new ConcurrentLinkedQueue<>();
//2. 入队操作
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
queue.offer(i);
}
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 5; i < 10; i++) {
queue.offer(i);
}
}
});
//3. 启动线程
thread1.start();
thread2.start();
thread1.join();
thread2.join();
//4. 出队操作
int size = queue.size();
for (int i = 0; i < size; i++) {
System.out.println(queue.poll());
}
System.out.println("出队成功, 元素个数: " + queue.size());
}
}
public class Demo06 {
public static void main(String[] args) throws Exception{
//1. 创建一个有界队列, 添加数据
ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(5);
//2. 添加元素
queue.put("aaa");
queue.put("bbb");
queue.put("ccc");
queue.put("ddd");
queue.put("eee");
System.out.println("已经添加了5个元素");
//queue.put("fff");//无法添加,因为队列此时满了
//System.out.println("已经添加了6个元素");
//3. 删除元素
queue.take();//删除第一个
System.out.println(queue.toString());
}
}
使用阻塞队列实现生产者和消费者
public class Demo07 {
public static void main(String[] args) {
//1. 创建队列
ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<>(6);
//2. 创建两个线程
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 30; i++) {
try {
queue.put(i);
System.out.println(Thread.currentThread().getName() + "生产了第" + i + "个面包");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}, "张三");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 30; i++) {
try {
queue.take();
System.out.println(Thread.currentThread().getName() + "消费了第" + i + "个面包");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}, "李四");
//3. 启动线程
t1.start();
t2.start();
}
}
链表结构实现, 有界队列. (默认上限Integer.MAX_VALUE)
public class Demo08 {
public static void main(String[] args) {
//1. 创建集合
ConcurrentHashMap<String, String> hashMap = new ConcurrentHashMap<>();
//2. 使用多线程添加数据
for (int i = 0; i < 5; i++) {
new Thread(new Runnable() {
@Override
public void run() {
for (int j = 0; j < 10; j++) {
hashMap.put(Thread.currentThread().getName()+ "---" + j, j + "");
System.out.println(hashMap);
}
}
}).start();
}
}
}
原文:https://www.cnblogs.com/MRASdoubleZ/p/14503013.html