java——多线程的实现方式、三种办法解决线程赛跑、多线程数据同步(synchronized)、死锁
多线程的实现方式:demo1、demo2
demo1:继承Thread类,重写run()方法
package thread_test;
public class ThreadDemo1 extends Thread {
ThreadDemo1(){
}
ThreadDemo1(String szName){
super(szName);
}
//重载run函数
public void run() {
for(int count = 1 , row = 1 ; row < 10 ; row ++ , count ++) {
for(int i = 0 ; i < count ; i ++) {
System.out.print("*");
}
System.out.println();
}
}
public static void main(String[] args) {
//线程赛跑
ThreadDemo1 td1 = new ThreadDemo1();
ThreadDemo1 td2 = new ThreadDemo1();
ThreadDemo1 td3 = new ThreadDemo1();
td1.start();
td2.start();
td3.start();
}
}
demo2:实现runnable接口,实现run()方法
package thread_test;
public class ThreadDemo2 implements Runnable{
public void run() {
for(int count = 1 , row = 1 ; row < 10 ; row ++ , count ++) {
for(int i = 0 ; i < count ; i ++) {
System.out.print("*");
}
System.out.println();
}
}
public static void main(String[] args) {
//存在线程赛跑问题
Runnable rb1 = new ThreadDemo2();
Runnable rb2 = new ThreadDemo2();
Runnable rb3 = new ThreadDemo2();
Thread td1 = new Thread(rb1);
Thread td2 = new Thread(rb2);
Thread td3 = new Thread(rb3);
td1.start();
td2.start();
td3.start();
}
}
demo3:两种方法解决进程赛跑问题
package thread_test; //两种方法解决线程赛跑
class ThreadWait extends Thread{ public ThreadWait() { } public ThreadWait(String name) {
super(name);
} @Override
public void run() {
for(int count = 1 , row = 1 ; row < 10 ; row ++ , count ++) {
for(int i = 0 ; i < count ; i ++) {
System.out.print("*");
}
System.out.println();
}
}
} public class ThreadDemo3{
public static void main(String[] args) {
ThreadDemo3 td = new ThreadDemo3();
// td.Method1();
td.Method2();
} public void Method1() {
ThreadWait tw1 = new ThreadWait();
ThreadWait tw2 = new ThreadWait();
tw1.start();
while(tw1.isAlive()) {
try{
Thread.sleep(100);
}catch(Exception e){
e.getMessage();
}
}
tw2.start();
} public void Method2() {
ThreadWait tw1 = new ThreadWait();
ThreadWait tw2 = new ThreadWait();
tw1.start();
try {
tw1.join(); // 等待该线程中止
}catch(Exception e){
e.toString();
}
tw2.start();
}
}
线程异步访问数据导致问题:
package thread_test; //线程异步访问数据导致问题
class ShareData{
public static String szData = "";
} class ThreadDemo extends Thread{ private static ShareData oShare; ThreadDemo(){
} ThreadDemo(String name, ShareData oShare){
super(name);
this.oShare = oShare;
} public void run() {
for(int i = 0 ; i < 5 ; i ++) {
if(this.getName().equals("th1")) {
oShare.szData = "这是第一个进程";
try {
Thread.sleep(100);
}catch(Exception e) { }
System.out.println(this.getName() + oShare.szData);
}else if(this.getName().equals("th2")) {
oShare.szData = "这是第二个进程";
try {
Thread.sleep(100);
}catch(Exception e) { }
System.out.println(this.getName() + oShare.szData);
}
}
}
} public class ThreadDemo5 { public static void main(String[] args) {
ShareData oShare = new ShareData();
ThreadDemo th1 = new ThreadDemo("th1", oShare);
ThreadDemo th2 = new ThreadDemo("th2", oShare);
th1.start();
th2.start();
}
}
得到的结果并不是我们想要的:

解决办法:
通过“锁”解决线程赛跑问题并实现多线程数据同步:
package thread_test;
class ShareData0{
public static String szData = "";
} class ThreadDemo0 extends Thread{ private static ShareData0 oShare; ThreadDemo0(){
} ThreadDemo0(String name, ShareData0 oShare){
super(name);
this.oShare = oShare;
} public void run() {
//同步快,并指出同步数据oShare
synchronized(oShare){
for(int i = 0 ; i < 5 ; i ++) {
if(this.getName().equals("th1")) {
oShare.szData = "这是第一个进程";
try {
Thread.sleep(100);
}catch(Exception e) { }
System.out.println(this.getName() + oShare.szData);
}else if(this.getName().equals("th2")) {
oShare.szData = "这是第二个进程";
try {
Thread.sleep(100);
}catch(Exception e) { }
System.out.println(this.getName() + oShare.szData);
}
}
}
}
}
public class ThreadDemo6 { public static void main(String[] args) {
ShareData0 oShare = new ShareData0();
ThreadDemo0 th1 = new ThreadDemo0("th1", oShare);
ThreadDemo0 th2 = new ThreadDemo0("th2", oShare); th1.start();
th2.start();
}
}
得到结果:

死锁:由于两个线程都在等待对方释放各自拥有的锁的现象称为死锁,这种现象往往是由于相互潜逃的synchronized代码段而造成的,所以少用synchronized嵌套。
下面是一个死锁的例子:
package thread_test;
public class LockedThread extends Thread{
private static Object A = new Object();
private static Object B = new Object();
private static boolean flag = true;
public static void main(String[] args) {
LockedThread th1 = new LockedThread();
LockedThread th2 = new LockedThread();
th1.start();
th2.start();
}
public void AccessA() {
flag = false;
synchronized(A) {
System.out.println("th1获得了A的锁");
try {
Thread.sleep(1000);
}catch(Exception e) {
}
System.out.println("th1还想要B的锁");
synchronized(B) {
System.out.println("th1获得了B的锁");
}
}
}
public void AccessB() {
flag = true;
synchronized(B) {
System.out.println("th2获得了B的锁");
try {
Thread.sleep(1000);
}catch(Exception e) {
}
System.out.println("th2还想要A的锁");
synchronized(A) {
System.out.println("th2获得了A的锁");
}
}
}
public void run(){
if(flag) {
AccessA();
}else {
AccessB();
}
}
}
显示结果:

程序没有结束 而是停在了这里,这就是死锁。
java——多线程的实现方式、三种办法解决线程赛跑、多线程数据同步(synchronized)、死锁的更多相关文章
- QThread 爬坑之旅(三种办法解决QObject: Cannot create children for a parent that is in a different thread)
Cannot create children for a parent that is in a different thread. 在Qt的官方文档,大家知道有两种方式使用QThread. You ...
- Java通过JDBC连接数据库的三种方式!!!并对数据库实现增删改查
前言 java连接数据库完整流程为: 1,获得驱动(driver),数据库连接(url),用户名(username),密码(password)基本信息的三种方式. 2,通过获得的信息完成JDBC实现连 ...
- java 实现md5加密的三种方式与解密
java 实现md5加密的三种方式 CreateTime--2018年5月31日15点04分 Author:Marydon 一.解密 说明:截止文章发布,Java没有实现解密,但是已有网站可以免费 ...
- Java连接Oracle数据库的三种连接方式
背景: 这两天在学习Oracle数据库,这里就总结下自己上课所学的知识,同时记录下来,方便整理当天所学下的知识,也同时方便日后自己查询. SQL语句的话,这里我就不多讲了,感觉和其他的数据库(MySQ ...
- Java遍历List集合的三种方法
Java遍历List集合的三种方法 List<String> list = new ArrayList<String>(); list.add("aaa") ...
- PHP修改memory_limit的三种办法
PHP修改memory_limit的三种办法 2010-06-11 10:57:11 分类: 可能是分词程序的问题.只要搜索的字段达到十个汉字以上,就会出现诸如以下的错误 Fatal error: ...
- C++ 继承方式 //语法:class 子类 :继承方式 父类 //继承方式 三种: //1.公共继承 //2.保护继承 //3.私有继承
1 //继承方式 2 //语法:class 子类 :继承方式 父类 3 //继承方式 三种: 4 //1.公共继承 5 //2.保护继承 6 //3.私有继承 7 8 #include <ios ...
- 三种方法解决android帮助文档打开慢
三种方法解决android帮助文档打开慢 经查是因为本地文档中的网页有如下两段js代码会联网加载信息,将其注释掉后就好了 <link rel="stylesheet" h ...
- C2B电商三种主要模式的分析_数据分析师
C2B电商三种主要模式的分析_数据分析师 在过去的一年中电商领域血雨腥风,尤其是天猫.京东.苏宁.当当.易讯等B2C电商打得不亦乐乎.而随着B2C领域竞争进入白热化阶段,C2B模式也在天猫" ...
随机推荐
- Vbs 脚本编程简明教程之一
—为什么要使用 Vbs ? 在 Windows 中,学习计算机操作也许很简单,但是很多计算机工作是重复性劳动,例如你每周也许需要对一些计算机文件进行复制.粘贴.改名.删除,也许你每天启动 计算机第一件 ...
- UITableView(可滚动到顶部和底部)
#import "RootViewController.h" #define width [UIScreen mainScreen].bounds.size.width #defi ...
- php学习笔记-关联数组
传统的数组定义方法如下: <?php $names[0]= 'chinese'; $names[1]= 'math'; $names[2]= 'english'; echo $names[2]; ...
- 算法Sedgewick第四版-第1章基础-2.1Elementary Sortss-002插入排序法(Insertion sort)
一.介绍 1.时间和空间复杂度 运行过程 2.特点: (1)对于已排序或接近排好的数据,速度很快 (2)对于部分排好序的输入,速度快 二.代码 package algorithms.elementar ...
- Entity Framework Tutorial Basics(4):Setup Entity Framework Environment
Setup Entity Framework Environment: Entity Framework 5.0 API was distributed in two places, in NuGet ...
- 数据结构_Summary
问题描述 可怜的 Bibi 丢了好几台手机以后,看谁都像是小偷,他已经在小本本上记下了他认为的各个地点的小偷数量.现在我们将 Bibi 的家附近的地形抽象成一棵有根树. 每个地点都是树上的一个节点,节 ...
- 点石成金:访客至上的网页设计秘笈(原书第2版) 中文PDF版
可用性设计是Web设计中最重要也是难度最大的一项任务.本书作者根据多年从业的经验,剖析用户的心理,在用户使用的模式.为扫描进行设计.导航设计.主页布局.可用性测试等方面提出了许多独特的观点,并给出了大 ...
- Oracle 函数-字符型函数
1.字符型函数 函数 说明 案例 结果 ASCII(X) 求字符X的ASCII码 select ASCII('A') FROM DUAL; 65 CHR(X) 求ASCII码对应的字符 select ...
- 【C#】ORM框架
ORM提供了实现持久化层的另一种模式,它采用映射元数据来描述对象关系的映射,使得ORM中间件能在任何一个应用的业务逻辑层和数据库层之间充当桥梁. Java典型的ORM框架有个:Hibernate,my ...
- 读取txt文件的简易算法
网友在问,从一个文本文件(txt)读取数据,并做简易算法.网友的原问题大约如下, 网友的问题,虽然说是全部是数字,但没有说明是否只有一行.因此Insus.NET在实现算法时,处理文本文件是否多行,是否 ...