java中多线程 - 多线程中的基本方法
介绍一下线程中基本的方法使用
线程睡眠sleep()
Thread.sleep(毫秒);我们可以通过sleep方法设置让线程睡眠。可以看到sleep是个静态方法
public static native void sleep(long var0) throws InterruptedException;
try {
System.out.println(new Date().getSeconds());
Thread.sleep(5000);
System.out.println(new Date().getSeconds());
} catch (InterruptedException e) {
e.printStackTrace();
}
setDaemon守护线程
非守护线程停止,那么守护线程自动退出
public static void main(String[] args) {
Thread thread1 = new Thread() {
@Override
public void run() {
super.run();
for(int i = 0; i < 5; i ++) {
System.out.println("非守护线程");
}
}
};
Thread thread2 = new Thread() {
@Override
public void run() {
for(int i = 0; i < 200; i ++) {
System.out.println("守护线程");
}
}
};
thread2.setDaemon(true);
thread1.start();
thread2.start();
}
可以很明显的看到thread2本应该执行200次输出,但是这里只输出了几行。因为当thread1执行完毕后,thread2作为守护线程就自动停止了。
多线程join
如果执行了join方法,那么停止当前线程,先跑执行了join()的线程。相当于插队执行。如下,在执行thread2线程的时候,如果i==20的时候,则让thread1插队先执行
public static void main(String[] args) {
final Thread thread1 = new Thread() {
@Override
public void run() {
super.run();
for(int i = 0; i < 500; i ++) {
System.out.println("thread1---" + i);
}
}
};
Thread thread2 = new Thread() {
@Override
public void run() {
for(int i = 0; i < 200; i ++) {
if (i == 20) {
try {
//插队执行
thread1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(i);
}
}
};
thread1.start();
thread2.start();
}
join()方法也可以传参数long 毫秒 join(毫秒)
表示让执行join的线程,插队执行XXX毫秒,过了时间后,两个线程交替执行
public static void main(String[] args) {
final Thread thread1 = new Thread() {
@Override
public void run() {
super.run();
for(int i = 0; i < 500; i ++) {
System.out.println("thread1---" + i);
}
}
};
Thread thread2 = new Thread() {
@Override
public void run() {
for(int i = 0; i < 200; i ++) {
if (i == 20) {
try {
//插队执行1毫秒
thread1.join(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(i);
}
}
};
thread1.start();
thread2.start();
}
yeild 礼让线程
yeild会让出cpu,让其他线程执行
public static void main(String[] args) {
final Thread thread1 = new Thread() {
@Override
public void run() {
super.run();
for(int i = 0; i < 500; i ++) {
System.out.println( getName() + "---" + i);
}
}
};
Thread thread2 = new Thread() {
@Override
public void run() {
for(int i = 0; i < 200; i ++) {
if (i % 5 == 0) {
Thread.yield();
}
System.out.println(getName() + "---" + i);
}
}
};
thread1.start();
thread2.start();
}
setPriority给线程设置优先级
默认优先级是5 最小1,最大10
越大优先级越高
public static void main(String[] args) {
final Thread thread1 = new Thread() {
@Override
public void run() {
super.run();
for(int i = 0; i < 500; i ++) {
System.out.println( getName() + "---" + i);
}
}
};
Thread thread2 = new Thread() {
@Override
public void run() {
for(int i = 0; i < 500; i ++) {
System.out.println(getName() + "---" + i);
}
}
};
//设置最大的线程优先级最大为10
thread1.setPriority(Thread.MIN_PRIORITY);
//设置最小的线程优先级,最小为1
thread2.setPriority(Thread.MAX_PRIORITY);
thread1.start();
thread2.start();
}
synchronized
同步代码块
当多线程并发,多段代码同时执行的时候。希望在执行其中代码的时候,cpu不切换线程
不用synchronized的情况
我们来看一下不用synchronized的情况会发生什么
public class ThreadSynchronied {
public static void main(String[] args) {
final Say say = new Say();
Thread thread1 = new Thread() {
@Override
public void run() {
for (int i = 0 ; i < 10000 ; i ++) {
say.say();
}
}
};
Thread thread2 = new Thread() {
@Override
public void run() {
for (int i = 0 ; i < 10000 ; i ++) {
say.say1();
}
}
};
//设置最大的线程优先级最大为10
thread1.setPriority(Thread.MIN_PRIORITY);
//设置最小的线程优先级,最小为1
thread2.setPriority(Thread.MAX_PRIORITY);
thread1.start();
thread2.start();
}
}
class Say {
void say() {
System.out.print("s ");
System.out.print("a ");
System.out.print("y ");
System.out.print("h ");
System.out.print("e ");
System.out.print("l ");
System.out.print("l ");
System.out.println("o");
}
void say1() {
System.out.print("1 ");
System.out.print("2 ");
System.out.print("3 ");
System.out.print("4 ");
System.out.print("5 ");
System.out.print("6 ");
System.out.print("7 ");
System.out.println("8");
}
}
我们发现有些输出并没有打印全,在执行线程thread1的过程中,cpu被thread2抢占。这种情况下,肯定是不符合我们的业务逻辑的。所以我们要保证线程执行了一个完整的方法后,cpu才会被其他线程抢占
使用synchronized
public class ThreadSynchronied {
public static void main(String[] args) {
final Say say = new Say();
Thread thread1 = new Thread() {
@Override
public void run() {
for (int i = 0 ; i < 10000 ; i ++) {
say.say();
}
}
};
Thread thread2 = new Thread() {
@Override
public void run() {
for (int i = 0 ; i < 10000 ; i ++) {
say.say1();
}
}
};
//设置最大的线程优先级最大为10
thread1.setPriority(Thread.MIN_PRIORITY);
//设置最小的线程优先级,最小为1
thread2.setPriority(Thread.MAX_PRIORITY);
thread1.start();
thread2.start();
}
}
class Say {
String s = "hahaah";
void say() {
synchronized (s) {
System.out.print("s ");
System.out.print("a ");
System.out.print("y ");
System.out.print("h ");
System.out.print("e ");
System.out.print("l ");
System.out.print("l ");
System.out.println("o");
}
}
void say1() {
synchronized (s) {
System.out.print("1 ");
System.out.print("2 ");
System.out.print("3 ");
System.out.print("4 ");
System.out.print("5 ");
System.out.print("6 ");
System.out.print("7 ");
System.out.println("8");
}
}
}
使用synchronized同步代码块后,就发现不会出现上述情况了
同步方法
public class ThreadSynchroniedMethod {
public static void main(String[] args) {
final Say say = new Say();
Thread thread1 = new Thread() {
@Override
public void run() {
for (int i = 0 ; i < 10000 ; i ++) {
say.say();
}
}
};
Thread thread2 = new Thread() {
@Override
public void run() {
for (int i = 0 ; i < 10000 ; i ++) {
say.say1();
}
}
};
//设置最大的线程优先级最大为10
thread1.setPriority(Thread.MIN_PRIORITY);
//设置最小的线程优先级,最小为1
thread2.setPriority(Thread.MAX_PRIORITY);
thread1.start();
thread2.start();
}
}
class Say {
//在方法上加锁
static synchronized void say() {
System.out.print("s ");
System.out.print("a ");
System.out.print("y ");
System.out.print("h ");
System.out.print("e ");
System.out.print("l ");
System.out.print("l ");
System.out.println("o");
}
static void say1() {
synchronized (Say.class) {
System.out.print("1 ");
System.out.print("2 ");
System.out.print("3 ");
System.out.print("4 ");
System.out.print("5 ");
System.out.print("6 ");
System.out.print("7 ");
System.out.println("8");
}
}
}
同步方法指的就是在方法上加锁
静态同步方法的所对象是该类的字节码对象
非静态的同步方法锁对象是this
多个线程使用同一资源锁,容易造成死锁
什么是死锁?
死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
线程安全类
Vector
StringBuffer
HashTable
线程不安全
ArrayList
StringBuilder
HashSet
java.util.Collections中有synchronizedList等方法,支持我们把线程不安全的集合转成线程安全的
学习笔记
多次启动一个线程是非法的
java中多线程 - 多线程中的基本方法的更多相关文章
- Java线程和多线程(二)——对象中的wait,notify以及notifyAll方法
Java对象中的wait,notify以及notifyAll方法 在Java的Object类中包含了3个final的方法,这三个方法允许线程来交流资源是否被锁定.这三个方法就是wait(),notif ...
- java多线程中wait/notify/sleep/join/yield方法以及多线程的六种状态
刚开始学线程的时候也是被这几个方法搞的云里雾里的,尤其是一开始看的毕老师的视频,老师一直在强调执行权和执行资格,看的有点懵逼,当然不是说毕老师讲的不好,就是自己有点没听明白,后来复习看了一些其他的博客 ...
- Java多线程中join、yield、sleep方法详解
在Java多线程编程中,Thread类是其中一个核心和关键的角色.因此,对该类中一些基础常用方法的理解和熟练使用是开发多线程代码的基础.本篇主要总结一下Thread中常用的一些静态方法的含义及代码中的 ...
- 详细分析 Java 中实现多线程的方法有几种?(从本质上出发)
详细分析 Java 中实现多线程的方法有几种?(从本质上出发) 正确的说法(从本质上出发) 实现多线程的官方正确方法: 2 种. Oracle 官网的文档说明 方法小结 方法一: 实现 Runnabl ...
- Java多线程入门中几个常用的方法
一.currentThread()方法 currentThread方法就是返回当前被调用的线程. 该方法为一个本地方法,原码如下: /** * Returns a reference to the c ...
- 黑马程序员_ JAVA中的多线程
------- android培训.java培训.期待与您交流! ---------- 尽管线程对象的常用方法可以通过API文档来了解,但是有很多方法仅仅从API说明是无法详细了解的. 本来打算用一节 ...
- 【转】Java多线程编程中易混淆的3个关键字( volatile、ThreadLocal、synchronized)总结
概述 最近在看<ThinKing In Java>,看到多线程章节时觉得有一些概念比较容易混淆有必要总结一下,虽然都不是新的东西,不过还是蛮重要,很基本的,在开发或阅读源码中经常会遇到,在 ...
- java中的多线程——进度1
import java.util.*;public static void main(String[] args) {/*final可以修饰类,方法,变量.final修饰的类不可以被继承.final修 ...
- JAVA并发七(多线程环境中安全使用集合API)
在集合API中,最初设计的Vector和Hashtable是多线程安全的.例如:对于Vector来说,用来添加和删除元素的方法是同步的.如果只有一个线程与Vector的实例交互,那么,要求获取和释放对 ...
- Java多线程编程中Future模式的详解
Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...
随机推荐
- C++ 变量判定的螺旋法则
C++ 中一个标识符配合着各种修饰界定符,使得标识符的本意不那么直观一眼就能看出,甚至需要仔细分析,才能知道该标识符的具体你含义. 比如: void (*signal(int, void (*fp)( ...
- node学习之路
现阶段开始学习使用node开发一个个人博客系统,nodejs 基于V8引擎,是一个让 JavaScript 运行在服务端的开发平台,功能强大 ,Node.js 可以作为服务器向用户提供服务,它跳过了 ...
- ppt课件动手动脑实际验证
1关于double精度 源代码:public class Doublejingdu { public static void main(String[] args) { System.out.prin ...
- VMbox 安装 LInux系统流程
STEP 1 文件--新建---(自定义高级)---(默认设置)---(稍后安装系统)---(Linux+选择版本)---(虚拟机名字+存放位置)---(处理器2+核数2)---(虚拟机内存)2G一般 ...
- Spring Boot 2.x基础教程:构建RESTful API与单元测试
首先,回顾并详细说明一下在快速入门中使用的@Controller.@RestController.@RequestMapping注解.如果您对Spring MVC不熟悉并且还没有尝试过快速入门案例,建 ...
- pyinstaller 打包exe程序读不到配置文件No such file
挺久没更新博客的,一来之前是觉得才疏学浅,记录下来的太简单没人看.二来时间上不是很充裕(不是借口,有时间打游戏,没时间总结) 偶然有一次发现同事在搜索解决问题的时候正在看我博客的解决思路,很奇妙的感觉 ...
- 编程小技巧之 Linux 文本处理命令
合格的程序员都善于使用工具,正所谓君子性非异也,善假于物也.合理的利用 Linux 的命令行工具,可以提高我们的工作效率. 本文简单的介绍三个能使用 Linux 文本处理命令的场景,给大家开阔一下思路 ...
- linux shell 统计当前目录下的文件个数
shell 统计当前目录下文件个数,使用管道组合命令: ls -1 | wc -l 解释: ls -1 表示一行一个列出文件名. wc -l 表示打印统计的行数. 两个命令通过管道连在一起表示打印列出 ...
- Rust到底值不值得学--Rust对比、特色和理念
前言 其实我一直弄不明白一点,那就是计算机技术的发展,是让这个世界变得简单了,还是变得更复杂了. 当然这只是一个玩笑,可别把这个问题当真. 然而对于IT从业者来说,这可不是一个玩笑.几乎每一次的技术发 ...
- 你不可错过的Java学习资源清单
学习Java和其他技术的资源其实非常多,但是我们需要取其精华去其糟粕,选择那些最好的,最适合我们的,同时也要由浅入深,先易后难.基于这样的一个标准,我在这里为大家提供一份Java的学习资源清单. Ja ...