直接上代码啦 不解释啦
概要
一、两个线程交替打印
(1)使用synchonized
public class PrintTask {
boolean isFirstStart = false;
public static void main(String[] args) {
PrintTask printTask = new PrintTask();
Thread t1 = new Thread(()->{
printTask.println1();
});
Thread t2 = new Thread(()->{
printTask.println2();
});
t2.start();
t1.start();
}
public synchronized void println1(){
try {
for (int i = 0; i < 10; i++) {
System.out.print(1);
// this.isFirstStart = true;//如果要求1先打印
this.notify();
this.wait();
}
this.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void println2(){
try {
// //如果要求1先打印
// while(!isFirstStart){
// this.wait();
// }
for (int i = 0; i < 10; i++) {
System.out.print(2);
this.notify();
this.wait();
}
this.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
(2)使用Lock-Condition
public class PrintTask {
boolean isFirstStart = false;
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
public static void main(String[] args) {
PrintTask printTask = new PrintTask();
Thread t1 = new Thread(()->{
printTask.println1();
});
Thread t2 = new Thread(()->{
printTask.println2();
});
t1.start();
t2.start();
}
public void println1(){
try {
lock.lock();
for(int i =0;i<10;i++){
System.out.print(1);
condition.signal();
condition.await();
}
condition.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void println2(){
try {
lock.lock();
for(int i =0;i<10;i++){
System.out.print(2);
condition.signal();
condition.await();
}
condition.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
(3)使用LockSupport
public class PrintTask {
static Thread t1 = null;
static Thread t2 = null;
public static void main(String[] args) {
t1 = new Thread(()->{
for(int i =0;i<10;i++){
System.out.print(1);
LockSupport.unpark(t2);
LockSupport.park();
}
});
t2 = new Thread(()->{
for(int i =0;i<10;i++){
LockSupport.park();
System.out.print(2);
LockSupport.unpark(t1);
}
});
t1.start();
t2.start();
}
}
二、三个线程交替打印
(1)使用Lock-Condition
public class PrintTask {
Lock lock = new ReentrantLock();
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
Condition condition3 = lock.newCondition();
int state =1;
public static void main(String[] args) {
PrintTask printTask = new PrintTask();
Thread t1 = new Thread(()->{
printTask.println1();
});
Thread t2 = new Thread(()->{
printTask.println2();
});
Thread t3 = new Thread(()->{
printTask.println3();
});
t1.start();
t2.start();
t3.start();
}
public void println1(){
try {
lock.lock();
while (state %3 != 1){
condition1.await();
}
for (int i = 0; i < 10; i++) {
System.out.print(1);
state++;
condition2.signal();
// condition1.await();
}
// state++;
// condition2.signal();
// System.out.println("state="+state);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void println2(){
try {
lock.lock();
while (state %3 != 2){
condition2.await();
}
for (int i = 0; i < 10; i++) {
System.out.print(2);
state++;
condition3.signal();
// condition2.await();
}
// state++;
// condition3.signal();
// System.out.println("state="+state);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void println3(){
try {
lock.lock();
while (state %3 != 0){
condition3.await();
}
for (int i = 0; i < 10; i++) {
System.out.print(3);
state++;
condition1.signal();
// condition3.await();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
(2)使用LockSupport
public class PrintTask {
static Thread t1 = null;
static Thread t2 = null;
static Thread t3 = null;
public static void main(String[] args) {
t1 = new Thread(()->{
for(int i =0;i<10;i++){
System.out.print(1);
LockSupport.unpark(t2);
LockSupport.park();
}
});
t2 = new Thread(()->{
for(int i =0;i<10;i++){
LockSupport.park();
System.out.print(2);
LockSupport.unpark(t3);
}
});
t3 = new Thread(()->{
for(int i =0;i<10;i++){
LockSupport.park();
System.out.print(3);
LockSupport.unpark(t1);
}
});
t1.start();
t2.start();
t3.start();
}
}
三、消费者和生产者模式
(1)使用synchronized
public class MyContainer<T> {
final LinkedList<T> list = new LinkedList<>();
int capacity = 10;
int count =0;
public static void main(String[] args) {
MyContainer<Integer> myContainer = new MyContainer();
Thread producer = new Thread(()->{
for(int i = 0;i<100;i++){
myContainer.put(i);
System.out.println("producer put "+ i);
}
});
Thread consumer = new Thread(()->{
for(int i = 0;i<100;i++){
Integer integer = myContainer.get();
System.out.println("consumer get "+integer);
}
});
consumer.start();
producer.start();
}
public synchronized void put(T t){
try {
while (list.size() == capacity) {
this.wait();
}
list.add(t);
this.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized T get(){
while (list.size() == 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
T t = null;
t = list.removeFirst();//需要移除的情况下
this.notify();
return t;
}
}
(2)使用Lock-Condition
public class MyContainer<T> {
LinkedList<T> list = new LinkedList<>();
int maxSize =5;
ReentrantLock lock = new ReentrantLock();
Condition producer = lock.newCondition();
Condition consumer = lock.newCondition();
public static void main(String[] args) {
MyContainer<String> c = new MyContainer<>();
//启动消费者线程
for(int i=0; i<10; i++) {
new Thread(()->{
for(int j=0; j<5; j++) System.out.println(c.get());
}, "c" + i).start();
}
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
//启动生产者线程
for(int i=0; i<2; i++) {
new Thread(()->{
for(int j=0; j<25; j++) c.put(Thread.currentThread().getName() + " " + j);
}, "p" + i).start();
}
}
public void put(T t){
lock.lock();
try {
while (list.size() == maxSize) {
producer.await();
}
list.add(t);
consumer.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
public T get(){
T t = null;
lock.lock();
try {
while (list.size() == 0) {
consumer.await();
}
t = list.removeFirst();
producer.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
return t;
}
}
(3)直接使用BlockingQueue
public class MyContainer<T> {
BlockingQueue<T> blockingQueue = new ArrayBlockingQueue<>(10);
public static void main(String[] args) {
MyContainer<Integer> objectMyContainer = new MyContainer<>();
Thread producer = new Thread(()->{
for(int i =0;i<10;i++){
try {
objectMyContainer.blockingQueue.put(i);
System.out.println("put "+i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread consumer = new Thread(()->{
for(int i =0;i<10;i++){
try {
Integer num = objectMyContainer.blockingQueue.take();
System.out.println("get "+num);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
consumer.start();
producer.start();
}
}