java线程
来源:互联网 发布:mac 不能剪切 编辑:程序博客网 时间:2024/06/03 14:11
多线程
多线程实际是调用的操作系统中多线程操作的接口,在多线程的操作系统中,线程是可以并行存在的,即在某一时刻,cpu可以同时运行多个线程(多核CPU)。操作系统对多线程的调度对于java来说是不可见,对程序员来说是不可知的,所以在多线程运行时会存在很多问题。
多线程编程的原因:节约资源,当多个用户在用一时间段操作服务器时,必须使用多线程才能达到极快的响应。
生命周期
线程有5种状态
1.新建状态:新建一个线程对象。
2.就绪状态:线程对象运行start()方法,进入就绪队列,等待jvm虚拟机调度机的调度。
3.运行状态:就绪线程执行run()方法,进入运行状态,根据run()方法的代码线程会进入就绪、阻塞、死亡状态。
4.阻塞状态:线程执行sleep、join等。
5.死亡状态:线程完成任务或执行其他命令时。
进程与线程
一个进程可以存在一个或多个线程。
线程是一条有序的操作。
Java线程实现
实现Runnable接口或继承Thread类
实现run函数,自己写start函数,在函数中初始化Thread对象并调用run()方法。
Runnable接口实现的线程是没有返回值的。
实现Runbable接口方式
public classRunnableDemo implements Runnable { private Thread thread; private String threadName; public RunnableDemo(String threadName) { this.threadName = threadName; } @SuppressWarnings("static-access") public void run() { System.out.println(threadName + "启动"); for (int i = 0; i < 4; i++) { System.out.println(threadName); try { thread.sleep(500); }catch(InterruptedException e) { e.printStackTrace(); continue; } } System.out.println(threadName + "关闭"); } public void start() { this.thread = new Thread(this, threadName); this.thread.start(); }}
测试类
public classRunnableDemoTest { public static void main(String[] args) { RunnableDemor1 = new RunnableDemo("线程1"); r1.start(); RunnableDemor2 = new RunnableDemo("线程2"); r2.start(); }}
实现Callable接口
Callable接口可以拿到线程返回值
public classCallableThreadTest implements Callable<Integer>{ @Override public Integer call() throws Exception { int i = 0; for (; i < 100; i++) { System.out.println(Thread.currentThread().getName()+ i); } return i; } public static void main(String[] args) { CallableThreadTestctt= newCallableThreadTest(); FutureTask<Integer>ft = new FutureTask<>(ctt); for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName()+ " 循环变量i的值" + i); if (i == 20) { new Thread(ft, "有返回值的线程").start(); } } try { System.out.println("子线程的返回值:"+ft.get()); }catch(InterruptedException | ExecutionException e) { e.printStackTrace(); } }}
实现线程安全的单例模式
先写一个线程不安全的写法
private static Bank bank; private Bank() {} public static Bank getBank() { if(bank == null) { bank= new Bank(); } returnbank;}
假设线程A和线程B同时访问到if (bank == null) ,且bank目前为空时,线程A和B都会去执行bank = new Bank();,那么单例就失效了。
解决方法一:方法加上同步锁关键字修饰
public synchronizedstaticBank getBankSY() { if (bank == null) { bank = new Bank(); } return bank;}
当使用同步锁时,所有线程执行getBankSY()方法都会阻塞,一次只能允许一个线程执行该方法。但这样十分消耗资源,如果单例已经初始化,这时再进行同步就没有必要了。可以使用双重检测。
private staticvolatileBank bank;public synchronizedstaticBank getBankDC() { if (bank == null) { synchronized (Bank.class) { if (bank == null) { bank = new Bank(); } } } return bank;}
当第一检测不为空时,就不会进入同步状态,阻塞线程了。
线程同步工具CountDownLatch
当一个线程需要等待其他线程全部执行完毕后,它再去执行时,可以使用CountDownLatch。先初始化一个CountDownLatch对象,每个线程结束时,执行.countDown方法,在需要等待的线程中执行.await()方法,它会阻塞该线程,知道所有countDown的线程执行完。
public voidtrueSinglon() { CountDownLatchcdl= newCountDownLatch(2); new Thread() { public void run() { b1 = Bank.getBankDC(); cdl.countDown(); } }.start(); new Thread() { public void run() { b2 = Bank.getBankDC(); cdl.countDown(); } }.start(); try { cdl.await(); System.out.println( "双重验证单例返回值比较:" + (b1==b2)); }catch(InterruptedException e) { e.printStackTrace(); }}
- Java线程:什么是线程
- Java线程:线程池
- java线程--线程退出
- JAVA-线程/线程锁
- Java线程:什么是线程
- Java线程:线程中断
- Java线程:线程状态
- Java线程: 线程调度
- Java线程:线程交互
- java--线程--线程池
- java 线程
- Java线程
- java线程
- java线程
- Java线程
- Java线程
- java线程
- JAVA 线程
- 排序算法(九)——八大排序算法总结
- thinkphp3.2.1分页路由
- 快速排序的稳定化实现
- js、jQuery、layer实现弹出层的打开、关闭
- java在list集合指定位置插入对象和js在数组指定位置插入对象的方法
- java线程
- ECMAScript6(6):数组的扩展
- 最全的常用正则表达式大全——包括校验数字、字符、一些特殊的需求等
- 进程间通信----信号量
- New Year Table
- EL表达式
- winpe下开启vs远调器
- 剑指offer:第29题寻找数组中出现次数超过一半的数字
- 混合开发,原生+html5