我是靠谱客的博主 怕黑薯片,这篇文章主要介绍新手学习多线程的详细思路和流程,现在分享给大家,希望可以做个参考。

  最近在博客园中逛,看到多线程想学习一下,虽然作者本人感觉挺详细的,但对于新手没学过多线程理解还是有难度的,最多也就是明白大概意思,自己写还是一片空白,我看过多个博客以后觉得还需要打代码才能彻底理解多线程,以下以一个经典多线程题目为例,一个菜鸟解题的具体步骤:

  题目:建立三个线程,A线程打印10次A,B线程打印10次B,C线程打印10次C,要求线程同时运行,交替打印10次ABC。

  1.看到三个线程,同时运行,交替打印,和大神解答写的各种流程、sleep、synchronized、wait、notify一阵头痛。还是自己慢慢来,打印10个A先。。

 

package main;
/**
*
* 多线程题目解答
* @author 光
* @version 2015年11月20日 上午10:46:53
*
*/
public class ManyThreadPrint implements Runnable {
public String name;
public ManyThreadPrint(String name){
this.name=name;
}
@Override
public void run() {
int count = 10;
while(count > 0){
System.out.print(name);
count--;
}
}
public static void main(String[] args) {
ManyThreadPrint mtpa = new ManyThreadPrint("A");
new Thread(mtpa).start();
}
}

  解析:使用实现Runnable接口的方式使用线程,main方法中添加实例使用构造器传参A,重写run()方法中循环打印10次

  运行结果如下:

AAAAAAAAAA

  2.十次A打印完成,哈哈,把B和C打印以下试试

package main;
/**
*
* 多线程题目解答
* @author 光
* @version 2015年11月20日 上午10:46:53
*
*/
public class ManyThreadPrint implements Runnable {
public String name;
public ManyThreadPrint(String name){
this.name=name;
}
@Override
public void run() {
int count = 10;
while(count > 0){
System.out.print(name);
count--;
}
}
public static void main(String[] args) {
ManyThreadPrint mtpa = new ManyThreadPrint("A");
ManyThreadPrint mtpb = new ManyThreadPrint("B");
ManyThreadPrint mtpc = new ManyThreadPrint("C");
new Thread(mtpa).start();
new Thread(mtpb).start();
new Thread(mtpc).start();
}
}

  解析:只是在main方法中添加两个实例把B和C穿进去,添加两个线程执行

  运行结果如下:

AAAAAAAAAABBBBBBBBBBCCCCCCCCCC

  手贱又运行一下:

AAAAAAAAAACCCCCCCCCCBBBBBBBBBB

  这怎么回事。。在试一下:

ABBBBBBBBBBAAAAAAAAACCCCCCCCCC

  好吧,结果10个A,10个B,10个C全部打印出来了,就是结果不固定。

  3.查了一下资料,原来是3个线程同时执行,顺序不固定。只好让后面的线程先等一下再执行:

package main;
/**
*
* 多线程题目解答
* @author 光
* @version 2015年11月20日 上午10:46:53
*
*/
public class ManyThreadPrint implements Runnable {
public String name;
public ManyThreadPrint(String name){
this.name=name;
}
@Override
public void run() {
int count = 10;
while(count > 0){
System.out.print(name);
count--;
}
}
public static void main(String[] args) throws InterruptedException {
ManyThreadPrint mtpa = new ManyThreadPrint("A");
ManyThreadPrint mtpb = new ManyThreadPrint("B");
ManyThreadPrint mtpc = new ManyThreadPrint("C");
new Thread(mtpa).start();
Thread.sleep(10);
new Thread(mtpb).start();
Thread.sleep(10);
new Thread(mtpc).start();
Thread.sleep(10);
}
}

  解析:有一点需要注意,Thread.sleep(10);是下一个线程启动需要等待的时间,由于最后结果需要交替打印,所以第三个线程执行后也有一个等待,相当于下轮的第一个线程等待。

  结果如下(执行几次都一样):

AAAAAAAAAABBBBBBBBBBCCCCCCCCCC

  3.接下来就是交替ABC按照大神的方法,建立3个对象,虽然是三个普通的Object,却在run()中通过同步、等待、释放锁来实现线程的执行顺序,先看一下代码:

package main;
/**
*
* 多线程题目解答
* @author 光
* @version 2015年11月20日 上午10:46:53
*
*/
public class ManyThreadPrint implements Runnable {
public String name;
public Object prev;
public Object self;
public ManyThreadPrint(String name, Object prev, Object self) {
this.name = name;
this.prev = prev;
this.self = self;
}
@Override
public void run() {
int count = 10;
while(count > 0){
synchronized (prev) {
synchronized (self) {
System.out.print(name);
count--;
self.notify();
}
try {
prev.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block

e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws InterruptedException {
Object a = new Object();
Object b = new Object();
Object c = new Object();
ManyThreadPrint mtpa = new ManyThreadPrint("A",c,a);
ManyThreadPrint mtpb = new ManyThreadPrint("B",a,b);
ManyThreadPrint mtpc = new ManyThreadPrint("C",b,c);
new Thread(mtpa).start();
Thread.sleep(10);
new Thread(mtpb).start();
Thread.sleep(10);
new Thread(mtpc).start();
Thread.sleep(10);
}
}

  解析:

  改变构造器,每次创建实例是除了打印的字符串,还有两个对象,这一点要注意,这两个对象只是普通的Object,跟线程没一毛线关系,只是通过线程对对象锁的操作来控制流程。关键代码在run()中的循环里面,一点一点来。

  这里synchronized (self)、synchronized (prev),self当前对象锁,prev前一个(前缀)对象锁,当线程获取两个对象锁时执行打印;需要注意。将synchronized (self)放入synchronized (prev)中表示打印A线程执行后,进入等待前置C对象的线程池里面,这样在打印C时唤醒一下C对象,那么打印C完成后就会立刻打印A,不过这样执行需要保证3个线程的启动顺序,即main方法中的Thread.sleep(10)。启动打印A线程时,打印A,唤醒自己,进入等待C的线程池,释放AC。当3个线程按照启动顺序完成时,即打印C线程完成后,会立刻打印A,打印A线程完成后,立刻打印B,依照顺序循环。

  也就是说,在3个线程启动完成后,已经将打印A的线程进入等待C对象的线程池里;将打印B的线程进入等待A对象的线程池里;将打印C的线程进入等待B对象的线程池里。这时按照打印A线程、打印B线程、打印C线程的顺序执行,就保证下一轮以打印A线程开始,从而保证以后打印顺序。

  在自己打代码的过程中发现了很多感觉看懂的时候没发现的东西,所以,学东西,最好自己要手打一遍。

转载于:https://www.cnblogs.com/xiaoguangit/p/4991825.html

最后

以上就是怕黑薯片最近收集整理的关于新手学习多线程的详细思路和流程的全部内容,更多相关新手学习多线程内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(51)

评论列表共有 0 条评论

立即
投稿
返回
顶部