- 案例一
- 案例二
- 案例三
- 案例四
- 案例五
- 案例六
- 案例七
实现一个容器,提供两个方法,add(),count() 写两个线程,线程1添加10个元素到容器中,线程2实现监控元素的个数,当个数到5个时,线程2给出提示并结束。
本案例我通过闭锁(也叫门栓锁)实现,实现如下:
package day_12_28.zuoye; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; public class AddAndCount { CountDownLatch cdl = new CountDownLatch(1); List案例二list = new ArrayList<>(); public static void main(String[] args) { var aac = new AddAndCount(); new Thread(aac::add, "A").start(); new Thread(aac::count, "B").start(); } void add() { for (int i = 0; i < 10; i++) { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } String item = String.format("%s - %d", "item", i); list.add(item); System.out.println(Thread.currentThread().getName() + ":" + item); if (i == 4) { cdl.countDown(); } } } void count() { try { cdl.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("程序结束..."); System.exit(0); } }
编写程序模拟死锁。
死锁,简单来说就是两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
下面我就模拟这一状态:
package day_12_28.zuoye; public class Deadlock { private final Object o1 = new Object(); private final Object o2 = new Object(); public static void main(String[] args) { Deadlock d = new Deadlock(); new Thread(d::m1).start(); new Thread(d::m2).start(); } void m1(){ System.out.println(Thread.currentThread().getName() + "启动等待..."); synchronized(o1){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized(o2){ System.out.println("哈哈.."); } } } void m2(){ System.out.println(Thread.currentThread().getName() + "启动等待..."); synchronized(o2){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized(o1){ System.out.println("哈哈.."); } } } }案例三
编写程序,实现三个线程,运行输出 A1 B2 C3 A4 B5 C6 ……
我这里用了两种方式去实现:
方式一:
用公平锁:
package day_12_28.zuoye; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.ReentrantLock; public class TurnNumber { AtomicInteger num = new AtomicInteger(0); private final ReentrantLock rl = new ReentrantLock(true); public void show() { for (; ; ) { rl.lock(); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } String tn = Thread.currentThread().getName(); int i = num.incrementAndGet(); String s = String.format("%s%d", tn, i); System.out.print(s + " "); if ("C".equals(tn)) { System.out.println(); } rl.unlock(); } } public static void main(String[] args) throws InterruptedException { TurnNumber tn = new TurnNumber(); Thread a = new Thread(tn::show, "A"); Thread b = new Thread(tn::show, "B"); Thread c = new Thread(tn::show, "C"); a.setPriority(Thread.MAX_PRIORITY); a.start(); b.setPriority(Thread.NORM_PRIORITY); b.start(); c.setPriority(Thread.MIN_PRIORITY); c.start(); } }
方式二:
用join() 方法
package day_12_28.zuoye; import java.util.concurrent.atomic.AtomicInteger; public class TurnNumber2 { AtomicInteger num = new AtomicInteger(0); public void show() { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } String tn = Thread.currentThread().getName(); int i = num.incrementAndGet(); String s = String.format("%s%d", tn, i); System.out.print(s + " "); if ("C".equals(tn)) { System.out.println(); } } public static void main(String[] args) throws InterruptedException { TurnNumber2 tn = new TurnNumber2(); while (true) { Thread a = new Thread(tn::show, "A"); Thread b = new Thread(tn::show, "B"); Thread c = new Thread(tn::show, "C"); a.setPriority(Thread.MAX_PRIORITY); a.start(); a.join(); b.setPriority(Thread.NORM_PRIORITY); b.start(); b.join(); c.setPriority(Thread.MIN_PRIORITY); c.start(); c.join(); } } }案例四
创建五个线程并进入等待状态,等两秒后主线程开始并释放全部线程,最后主线程结束
本案例我用的是wait() 与notifyAll()组合形式;
package day_12_27; import java.util.concurrent.TimeUnit; public class WaitAndNotify { public static void main(String[] args) { Object co = new Object(); for (int i = 0; i < 5; i++) { MyThread t = new MyThread("Thread" + i, co); t.start(); } try { TimeUnit.SECONDS.sleep(2); System.out.println("-----Main Thread notify-----"); synchronized (co) { //co.notify(); co.notifyAll(); } TimeUnit.SECONDS.sleep(2); System.out.println("Main Thread is end."); } catch (InterruptedException e) { e.printStackTrace(); } } static class MyThread extends Thread { private String name; private Object co; public MyThread(String name, Object o) { this.name = name; this.co = o; } @Override public void run() { System.out.println(name + " is waiting."); try { synchronized (co) { co.wait(); } System.out.println(name + " has been notified."); } catch (InterruptedException e) { e.printStackTrace(); } } } }案例五
用五个线程实现,求123456789 之间放±和100的表达式,如果一个线程求出结果,立即告诉其它停止。
这里我用到了AtomicBoolean原子类来保证数据的原子性:
package day_12_27.zuoye; import java.util.Random; import java.util.concurrent.atomic.AtomicBoolean; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Number100 { //原子类,保证原子性 AtomicBoolean ab = new AtomicBoolean(true); public void show() { String[] ss = {"", "+", "-"}; StringBuilder sbu = new StringBuilder(); sbu.append("1"); Random random = new Random(); while (ab.get()) { for (int i = 2; i < 9; i++) { sbu.append(ss[random.nextInt(3)]); sbu.append(i); } Pattern p = Pattern.compile("[0-9]+|-[0-9]+"); Matcher m = p.matcher(sbu.toString()); int sum = 0; while (m.find()) { sum += Integer.parseInt(m.group()); } if (sum == 100) { ab.set(false); System.out.println(Thread.currentThread().getName() + ":" + sbu.toString() + " = 100"); } sbu.delete(1, sbu.length()); } } public static void main(String[] args) { var n = new Number100(); for (int i = 0; i < 5; i++) { new Thread(n::show).start(); } } }
模拟经典问题,生产者-消费者问题:
方式一:
package day_12_28.zuoye; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class ProductorAndConsumerForLock { public static void main(String[] args) { Clerk1 clerk1 = new Clerk1(); Productor1 pro = new Productor1(clerk1); Consumer1 con = new Consumer1(clerk1); new Thread(pro, "生产者 A").start(); new Thread(con, "消费者 B").start(); // new Thread(pro, "生产者 C").start(); // new Thread(con, "消费者 D").start(); } } class Clerk1 { private int product = 0; private Lock lock = new ReentrantLock(); private Condition condition = lock.newCondition(); // 进货 public void get() { lock.lock(); try { if (product >= 1) { // 为了避免虚假唤醒,应该总是使用在循环中。 System.out.println("产品已满!"); try { condition.await(); } catch (InterruptedException e) { } } System.out.println(Thread.currentThread().getName() + " : " + ++product); condition.signalAll(); } finally { lock.unlock(); } } // 卖货 public void sale() { lock.lock(); try { if (product <= 0) { System.out.println("缺货!"); try { condition.await(); } catch (InterruptedException e) { } } System.out.println(Thread.currentThread().getName() + " : " + --product); condition.signalAll(); } finally { lock.unlock(); } } } // 生产者 class Productor1 implements Runnable { private Clerk1 clerk1; public Productor1(Clerk1 clerk1) { this.clerk1 = clerk1; } @Override public void run() { for (int i = 0; i < 20; i++) { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } clerk1.get(); } } } // 消费者 class Consumer1 implements Runnable { private Clerk1 clerk1; public Consumer1(Clerk1 clerk1) { this.clerk1 = clerk1; } @Override public void run() { for (int i = 0; i < 20; i++) { clerk1.sale(); } } }
方式二:
package day_12_28.zuoye; public class ProductorAndConsumer { public static void main(String[] args) { Clerk clerk = new Clerk(); Productor pro = new Productor(clerk); Consumer cus = new Consumer(clerk); new Thread(pro, "生产者 A").start(); new Thread(cus, "消费者 B").start(); new Thread(pro, "生产者 C").start(); new Thread(cus, "消费者 D").start(); } } //店员 class Clerk { private int product = 0; //进货 public synchronized void get() {//循环次数:0 //为了避免虚假唤醒问题,应该总是使用在循环中 while (product >= 1) { System.out.println("产品已满!"); try { this.wait(); } catch (InterruptedException e) { } } System.out.println(Thread.currentThread().getName() + " : " + ++product); this.notifyAll(); } //卖货 public synchronized void sale() {//product = 0; 循环次数:0 while (product <= 0) { System.out.println("缺货!"); try { this.wait(); } catch (InterruptedException e) { } } System.out.println(Thread.currentThread().getName() + " : " + --product); this.notifyAll(); } } //生产者 class Productor implements Runnable { private Clerk clerk; public Productor(Clerk clerk) { this.clerk = clerk; } @Override public void run() { for (int i = 0; i < 20; i++) { try { Thread.sleep(200); } catch (InterruptedException e) { } clerk.get(); } } } //消费者 class Consumer implements Runnable { private Clerk clerk; public Consumer(Clerk clerk) { this.clerk = clerk; } @Override public void run() { for (int i = 0; i < 20; i++) { clerk.sale(); } } }案例七
开十个线程打印输出1~10000中偶数的值,计算总耗时
我采用的是闭锁机制:
package day_12_28.zuoye; import java.util.concurrent.CountDownLatch; public class CountTime { static CountDownLatch cdl = new CountDownLatch(10); void show() { for (int i = 0; i < 10000; i++) { if (i % 2 == 0) { System.out.println(Thread.currentThread().getName() + ":" + i); } } cdl.countDown(); } public static void main(String[] args) { CountTime ct = new CountTime(); long start = System.currentTimeMillis(); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } for (int i = 0; i < 10; i++) { new Thread(ct::show).start(); } try { cdl.await(); } catch (InterruptedException e) { e.printStackTrace(); } long end = System.currentTimeMillis(); System.out.println((end - start - 100) + "--------------"); } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)