第一种:extends Thread类
第二种:implements Runnable接口
第三种:实现callable接口
第四种:使用线程池
package com.xyz.java2; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; /*创建多线程的方式: 1.继承Thread 2.实现Runnable 3.实现Callable */ class MyThread01 extends Thread { @Override public void run() { System.out.println("-----MyThread01"); } } class MyThread02 implements Runnable { public void run() { System.out.println("-----MyThread02"); } } class MyThread03 implements Callable<Integer> { @Override public Integer call() throws Exception { System.out.println("-----MyThread03"); return 200; } } public class ThreadNew { public static void main(String[] args) { new MyThread01().start(); new Thread(new MyThread02()).start(); FutureTask<Integer> futureTask = new FutureTask<Integer>(new MyThread03()); new Thread(futureTask).start(); try { Integer value = futureTask.get(); System.out.println(value); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } }
package com.xyz.interview; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; //创建并使用多线程的第四种方法:使用线程池 class MyThread implements Runnable { @Override public void run() { for (int i = 1; i <= 100; i++) { System.out.println(Thread.currentThread().getName() + ":" + i); } } } public class ThreadPool { public static void main(String[] args) { // 1.调用Executors的newFixedThreadPool(),返回指定线程数量的ExecutorService ExecutorService pool = Executors.newFixedThreadPool(10); // 2.将Runnable实现类的对象作为形参传递给ExecutorService的submit()方法中,开启线程 // 并执行相关的run() pool.execute(new MyThread()); pool.execute(new MyThread()); pool.execute(new MyThread()); // 3.结束线程的使用 pool.shutdown(); } }
1.编写synchronized同步代码块
2.编写synchronized同步方法
3.使用lock()和unlock()方法
1.任意对象都可以作为同步锁。 所有对象都自动含有单一的锁(监视器)
2.同步方法的锁:静态方法(类名.class) 、 非静态方法(this)
3.同步代码块:自己指定, 很多时候也是指定为this或类名.class
需要注意的是:
1.必须确保使用同一个资源的多个线程共用一把锁, 这个非常重要, 否则就
无法保证共享资源的安全
2.一个线程类中的所有静态方法共用同一把锁(类名.class) , 所有非静态方
法共用同一把锁(this) , 同步代码块(指定需谨慎)
class A{ private final ReentrantLock lock = new ReenTrantLock(); public void m(){ lock.lock(); try{ //保证线程安全的代码; } finally{ lock.unlock(); } } }
1.Lock是显式锁(手动开启和关闭锁,别忘记关闭锁), synchronized是
隐式锁,出了作用域自动释放
2.Lock只有代码块锁, synchronized有代码块锁和方法锁
3.使用Lock锁, JVM将花费较少的时间来调度线程,性能更好。并且具有
更好的扩展性(提供更多的子类)
效果:调用此方法后,当前线程将释放对象监控权 ,使当前线程进入等待(某对象)状态 ,直到另一线程对该对象发出 notify(或notifyAll) 为止,
使用条件:当前线程必须具有对该对象的监控权(加锁)
功能:唤醒等待该对象监控权的一个/所有线程
调用方法的必要条件:当前线程必须具有对该对象的监控权(加锁)
class Clerk { // 售货员 private int product = 0; public synchronized void addProduct() { if (product >= 20) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } else { product++; System.out.println("生产者生产了第" + product + "个产品"); notifyAll(); } } public synchronized void getProduct() { if (this.product <= 0) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } else { System.out.println("消费者取走了第" +product + "个产品"); product--; notifyAll(); } } } class Productor implements Runnable { // 生产者 Clerk clerk; public Productor(Clerk clerk) { this.clerk = clerk; } public void run() { System.out.println("生产者开始生产产品"); while (true) { try { Thread.sleep((int) Math.random() * 1000); } catch (InterruptedException e) { e.printStackTrace(); } clerk.addProduct(); } } } class Consumer implements Runnable { // 消费者 Clerk clerk; public Consumer(Clerk clerk) { this.clerk = clerk; } public void run() { System.out.println("消费者开始取走产品"); while (true) { try { Thread.sleep((int) Math.random() * 1000); } catch (InterruptedException e) { e.printStackTrace(); } clerk.getProduct(); } } } public class ProductTest { public static void main(String[] args) { Clerk clerk = new Clerk(); Thread productorThread = new Thread(new Productor(clerk)); Thread consumerThread = new Thread(new Consumer(clerk)); productorThread.start(); consumerThread.start(); } }