1.死锁
public class DeadLockDemo { private static Object resource1 = new Object();//资源 1 private static Object resource2 = new Object();//资源 2 public static void main(String[] args) { new Thread(() -> { synchronized (resource1) { System.out.println(Thread.currentThread() + "get resource1"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread() + "waiting get resource2"); synchronized (resource2) { System.out.println(Thread.currentThread() + "get resource2"); } } }, "线程 1").start(); new Thread(() -> { synchronized (resource2) { System.out.println(Thread.currentThread() + "get resource2"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread() + "waiting get resource1"); synchronized (resource1) { System.out.println(Thread.currentThread() + "get resource1"); } } }, "线程 2").start(); } } 结果: Thread[线程 1,5,main]get resource1 Thread[线程 2,5,main]get resource2 Thread[线程 2,5,main]waiting get resource1 Thread[线程 1,5,main]waiting get resource2
修改:
我们对线程 2 的代码修改成下面这样就不会产生死锁了。 new Thread(() -> { synchronized (resource1) { System.out.println(Thread.currentThread() + "get resource1"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread() + "waiting get resource2"); synchronized (resource2) { System.out.println(Thread.currentThread() + "get resource2"); } } }, "线程 2").start();
结果: Thread[线程 1,5,main]get resource1 Thread[线程 1,5,main]waiting get resource2 Thread[线程 1,5,main]get resource2 Thread[线程 2,5,main]get resource1 Thread[线程 2,5,main]waiting get resource2 Thread[线程 2,5,main]get resource2
2.多线程有哪几种创建方式?
1.继承Thread类来创建线程
public class ThreadTest {
public static void main(String[] args) {
//设置线程名字
Thread.currentThread().setName("main thread");
MyThread myThread = new MyThread();
myThread.setName("子线程:");
//开启线程
myThread.start();
for(int i = 0;i<5;i++){
System.out.println(Thread.currentThread().getName() + i);
}
}
}
class MyThread extends Thread{
//重写run()方法
public void run(){
for(int i = 0;i < 10; i++){
System.out.println(Thread.currentThread().getName() + i);
}
}
}
2.实现Runnable接
需要实现 run() 方法。
通过 Thread 调用 start() 方法来启动线程。
public class RunnableTest { public static void main(String[] args) { //设置线程名字 Thread.currentThread().setName("main thread:"); Thread thread = new Thread(new MyRunnable()); thread.setName("子线程:"); //开启线程 thread.start(); for(int i = 0; i <5;i++){ System.out.println(Thread.currentThread().getName() + i); } } } class MyRunnable implements Runnable { @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + i); } } }
3.实现Callable接口 与 Runnable 相比,Callable 可以有返回值,返回值通过 FutureTask 进行封装。 public class CallableTest { public static void main(String[] args) { //执行Callable 方式,需要FutureTask 实现实现,用于接收运算结果 FutureTask<Integer> futureTask = new FutureTask<Integer>(new MyCallable()); new Thread(futureTask).start(); //接收线程运算后的结果 try { Integer sum = futureTask.get(); System.out.println(sum); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } } class MyCallable implements Callable<Integer> { @Override public Integer call() throws Exception { int sum = 0; for (int i = 0; i < 100; i++) { sum += i; } return sum; } }
4.线程池实现 public class ThreadPoolExecutorTest { public static void main(String[] args) { //创建线程池 ExecutorService executorService = Executors.newFixedThreadPool(10); ThreadPool threadPool = new ThreadPool(); for(int i =0;i<5;i++){ //为线程池分配任务 executorService.submit(threadPool); } //关闭线程池 executorService.shutdown(); } } class ThreadPool implements Runnable { @Override public void run() { for(int i = 0 ;i<10;i++){ System.out.println(Thread.currentThread().getName() + ":" + i); } } }
5.实现多个线程顺序打印abc
class printABC{ ReentrantLock lock = new ReentrantLock(); Condition conditionA = lock.newCondition(); Condition conditionB = lock.newCondition(); Condition conditionC = lock.newCondition(); volatile int value = 0; private int count ; public printABC(int count ) { this.count = count; } public void printABC() { new Thread(new ThreadA()).start(); new Thread(new ThreadB()).start(); new Thread(new ThreadC()).start(); } class ThreadA implements Runnable { @Override public void run() { lock.lock(); try { for (int i = 0; i < count; i++) { while (value % 3!= 0) { conditionA.await(); } System.out.println("A"); conditionB.signal(); value++; } }catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } } class ThreadB implements Runnable { @Override public void run() { lock.lock(); try { for (int i = 0; i < count; i++) { while (value % 3!= 1) { conditionB.await(); } System.out.println("B"); conditionC.signal(); value++; } }catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } } class ThreadC implements Runnable { @Override public void run() { lock.lock(); try { for (int i = 0; i < count; i++) { while (value % 3!= 2) { conditionC.await(); } System.out.println("C"); conditionA.signal(); value++; } }catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } } public static void main(String[] args) { printABC test = new printABC(1); test.printABC(); } }