package java4;
/**
* 使用同步机制将单例模式中的懒汉式改为线程安全的
*
* @author Baobao
* @create 2021-08-02 8:25
*/
public class BankTest {
}
class Bank{
private Bank(){
}
private static Bank instance=null;
public static Bank getInstance(){
//方式1:效率稍差
// synchronized (Bank.class){
// if(instance==null){
// instance=new Bank();
// return instance;
// }
// return instance;
// }
//方式2:
if(instance==null){
synchronized (Bank.class){
if(instance==null){
instance=new Bank();
return instance;
}
}
}
return instance;
}
}
package java4.exer1;
/**
* 线程通信的例子:交替打印1~100,两个线程
*
* 三个方法:
* wait();一旦执行,线程就进入阻塞,并释放同步监视器
* notify();一旦执行此方法,就会唤醒被wait的线程,如果有多个线程wait,就唤醒优先级高的
* notifyAll();唤醒所有的wait的线程
*
*
* 注意点:wait,notify和notifyAll只能出现在同步代码快或者是同步方法中
* 这三个方法的调用者必须是同步代码快或同步方法中的同步监视器!!!!!否则会出现异常
* 这三个方法是定义在java.lang.object类包中的
*
*
* 面试题:sleep和wait方法的异同?
* 1.相同点:都可以让当前线程进入阻塞状态
* 2.不同点:1)两个方法声明的位置不一样,sleep在Thread中,wait在object中
* 2)调用的范围,要求不一样,sleep没什么要求,wait一定要在同步代码块或者是同步方法中
* 3)wait会释放锁,sleep不会
*
*
*
* @author Baobao
* @create 2021-08-02 16:17
*/
class Number implements Runnable{
private int number;
@Override
public void run() {
while(true){
synchronized (this){
notify();
if(number<=100){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+":"+number);
number++;
try {//使得调用如下wait方法的线程进入阻塞状态
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
break;
}
}
}
}
}
public class CommnuicationTest {
public static void main(String[] args) {
Number num=new Number();
Thread t1=new Thread(num);
Thread t2=new Thread(num);
t1.setName("线程1");
t2.setName("线程2");
t1.start();
t2.start();
}
}
package java4.exer1;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/**
*
* 创建线程的方式三:实现Callable接口的方式----jdk5.0新增的
*
* 如何理解callable比runnable更强大?(实现多线程)
* 1.call方法可以有返回值
* 2.call方法可以抛出异常,被外面的操作捕获,获取异常信息
* 3.callable是支持泛型的
*
*
*
*
* @author Baobao
* @create 2021-08-02 18:32
*/
class NumberThread implements Callable{
@Override
public Object call() throws Exception {
int sum=0;
for (int i = 1; i <=100 ; i++) {
if(i%2==0){
System.out.println(i);
sum+=i;
}
}
return sum;
}
}
public class ThreadNew {
public static void main(String[] args) {
//创建callable接口实现类的对象
NumberThread numberThread=new NumberThread();
//将此callable接口的实现类对象传入futuretask构造器中,去创造futuretask对象
FutureTask fu = new FutureTask(numberThread);
//将futuretask对象作为参数传入thread中,调用start方法
new Thread(fu).start();
try {
//get的返回值即为futuretask的构造器参数的callable实现类重写的call方法的返回值
Object sum=fu.get();
System.out.println(sum);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
package java4.exer1;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
/**
*
* 创建线程的方式4:线程池
* 好处1:提高响应速度
* 好处2:降低资源消耗(重复利用线程,不用每次都创建新的)
* 好处3:便于管理
*
* @author Baobao
* @create 2021-08-02 20:52
*/
class NumberThread1 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if(i%2==0){
System.out.println(Thread.currentThread().getName()+" "+i);
}
}
}
}
class NumberThread2 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if(i%2!=0){
System.out.println(Thread.currentThread().getName()+" "+i);
}
}
}
}
public class ThreadPool {
public static void main(String[] args) {
//提供指定线程数量的线程池
ExecutorService service = Executors.newFixedThreadPool(10);
ThreadPoolExecutor service1=(ThreadPoolExecutor)service;
//设置线程池的属性
//System.out.println(service.getClass());
service1.setCorePoolSize(15);
//提供实现runnable或者callable接口的实现类对象
service.execute(new NumberThread1());//适合适用于runnable
service.execute(new NumberThread2());
// service.submit();//适合适用于callable
service.shutdown();
}
}