Java教程

多线程

本文主要是介绍多线程,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

多线程

一、多线程的创建

第一种: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()方法

synchronized:

1.任意对象都可以作为同步锁。 所有对象都自动含有单一的锁(监视器)
2.同步方法的锁:静态方法(类名.class) 、 非静态方法(this)
3.同步代码块:自己指定, 很多时候也是指定为this或类名.class
需要注意的是:
1.必须确保使用同一个资源的多个线程共用一把锁, 这个非常重要, 否则就
无法保证共享资源的安全
2.一个线程类中的所有静态方法共用同一把锁(类名.class) , 所有非静态方
法共用同一把锁(this) , 同步代码块(指定需谨慎)

lock()和unlock()

class A{
    private final ReentrantLock lock = new ReenTrantLock();
    public void m(){
        lock.lock();
        try{
          //保证线程安全的代码;
            }
        finally{
          lock.unlock();
        }
    }
}

synchronized 与 Lock 的对比

1.Lock是显式锁(手动开启和关闭锁,别忘记关闭锁), synchronized是
隐式锁,出了作用域自动释放
2.Lock只有代码块锁, synchronized有代码块锁和方法锁
3.使用Lock锁, JVM将花费较少的时间来调度线程,性能更好。并且具有
更好的扩展性(提供更多的子类)

三、线程通信中的常用方法

wait()

效果:调用此方法后,当前线程将释放对象监控权 ,使当前线程进入等待(某对象)状态 ,直到另一线程对该对象发出 notify(或notifyAll) 为止,
使用条件:当前线程必须具有对该对象的监控权(加锁)

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();
    }
}
这篇关于多线程的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!