多线程的实现方式: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)、死锁的更多相关文章

  1. 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 ...

  2. Java通过JDBC连接数据库的三种方式!!!并对数据库实现增删改查

    前言 java连接数据库完整流程为: 1,获得驱动(driver),数据库连接(url),用户名(username),密码(password)基本信息的三种方式. 2,通过获得的信息完成JDBC实现连 ...

  3. java 实现md5加密的三种方式与解密

      java 实现md5加密的三种方式 CreateTime--2018年5月31日15点04分 Author:Marydon 一.解密 说明:截止文章发布,Java没有实现解密,但是已有网站可以免费 ...

  4. Java连接Oracle数据库的三种连接方式

    背景: 这两天在学习Oracle数据库,这里就总结下自己上课所学的知识,同时记录下来,方便整理当天所学下的知识,也同时方便日后自己查询. SQL语句的话,这里我就不多讲了,感觉和其他的数据库(MySQ ...

  5. Java遍历List集合的三种方法

    Java遍历List集合的三种方法 List<String> list = new ArrayList<String>(); list.add("aaa") ...

  6. PHP修改memory_limit的三种办法

     PHP修改memory_limit的三种办法 2010-06-11 10:57:11 分类: 可能是分词程序的问题.只要搜索的字段达到十个汉字以上,就会出现诸如以下的错误 Fatal error: ...

  7. C++ 继承方式 //语法:class 子类 :继承方式 父类 //继承方式 三种: //1.公共继承 //2.保护继承 //3.私有继承

    1 //继承方式 2 //语法:class 子类 :继承方式 父类 3 //继承方式 三种: 4 //1.公共继承 5 //2.保护继承 6 //3.私有继承 7 8 #include <ios ...

  8. 三种方法解决android帮助文档打开慢

    三种方法解决android帮助文档打开慢   经查是因为本地文档中的网页有如下两段js代码会联网加载信息,将其注释掉后就好了 <link rel="stylesheet" h ...

  9. C2B电商三种主要模式的分析_数据分析师

    C2B电商三种主要模式的分析_数据分析师 在过去的一年中电商领域血雨腥风,尤其是天猫.京东.苏宁.当当.易讯等B2C电商打得不亦乐乎.而随着B2C领域竞争进入白热化阶段,C2B模式也在天猫" ...

随机推荐

  1. 自己实现 String 类

    实现Stirng类:构造函数.复制构造.拷贝构造.重载<<符号(友元) #include <iostream> #include <string.h> #inclu ...

  2. leetCode130. Surrounded Regions--广度优先遍历算法

    Problem: Given a 2D board containing 'X' and 'O' (the letter O), capture all regions surrounded by ' ...

  3. C/C++中struct/union/class内存对齐

    struct/union/class内存对齐原则有四个: 1).数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储 ...

  4. 巧用 git rebase 合并多个 commit。

    一.为什么需要合并多个 commit 呢?   有时候,我们开发一个功能. 修修补补 commit 了很多次,过多的 commit 会显得很复杂. 不够直观,不能比较清晰查看那些 commit 是对应 ...

  5. 序列化+fastjson和java各种数据对象相互转化

    序列化的定义 序列化就是一种用来处理对象流的机制 所谓对象流也就是将对象的内容进行流化.可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间. 序列化是将对象转换为容易传输的格式的过程 例 ...

  6. Java 分析模板方法设计模型

    http://www.cnblogs.com/maowang1991/archive/2013/04/15/3023236.html //父类 abstract class Operate{ prot ...

  7. 多线程学习-基础( 十一)synchronized关键字修饰方法的简单案例

    一.本案例设计到的知识点 (1)Object的notify(),notifyAll(),wait()等方法 (2)Thread的sleep(),interrupt(). (3)如何终止线程. (4)如 ...

  8. WebGoat系列实验Cross-Site Scripting (XSS)

    WebGoat系列实验Cross-Site Scripting (XSS) PhishingTitle 本次实验是在一个已知存在XSS漏洞的页面进行钓鱼攻击.通过使用XSS与HTML注入,在页面中注入 ...

  9. 通过ADB命令行卸载或删除你的Android设备中的应用(转载)

    转自:http://mytiankong.com/?p=11755 如果你对你的Android设备在与命令行的交互间有一定的兴趣,那你可能想学习一些使用ADB卸载设备中已安装应用的技巧.为了使这种方法 ...

  10. c语言常使用的函数,见到一个记一个

    1.strdup() 功能:克隆一个副本,具有独立的内存空间 声明:char *strdup(char *str): 原型: char * __strdup (const char *s) { siz ...