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模式也在天猫" ...
随机推荐
- 【转】nginx location匹配规则
转载请保留:http://www.nginx.cn/115.html location匹配命令 ~ #波浪线表示执行一个正则匹配,区分大小写~* #表示执行一个正则匹配,不区分大小写^ ...
- Django框架 之 admin管理工具(源码解析)
浏览目录 单例模式 admin执行流程 admin源码解析 单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在 ...
- rest-framework组件 之 渲染器与版本
浏览目录 渲染器 版本 渲染器 规定页面显示的效果(无用,了解即可). 局部渲染 只返回json数据. 效果: 看另一种情况: 既返回json数据,又嵌套在html中.注意:容易出bug. 效果如下: ...
- Git 之 github分享代码
作为一个技术人员还是脱离不了屌丝的本质,所以每天都是逛逛github,看看别人有什么好的项目,自己可以给他挑挑bug也可以提供自己的水平,但是别人不那怎么才能给别人贡献代码呢?那就是fork了.... ...
- Flask框架 之 功能详解
浏览目录 配置文件 路由系统 视图 请求相关 响应 模板渲染 session 闪现 中间件 蓝图(blueprint) 特殊装饰器 配置文件 知识点 给你一个路径 “settings.Foo”,可以找 ...
- Entity Framework Code-First(17):Database Initialization Strategy
Database Initialization Strategies in Code-First: You already created a database after running your ...
- Ubuntu 切换到桌面 快捷键设置
设置完以上步骤后,这接windows系统键+d,即可切换到桌面. ps:按Alt+Tab键,可以切换到自己想要的图标进程.
- Linux sogou input method
afda@afda-Y720-15IKB:~$ wget "http://pinyin.sogou.com/linux/download.php?f=linux&bit=64&quo ...
- java代理模式实例讲解
下面这个是设计模式课上的例子: import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import ...
- Dojo Javascript 编程规范(转)
前言 相当不错的 Javascript 编程风格规范,建议大家采用此规范编写 Javascript.原文链接: http://dojotoolkit.org/developer/StyleGuide ...