欢迎您光临本小站。希望您在这里可以找到自己想要的信息。。。

张孝祥老师-java并发编程听课笔记(二)

java water 2961℃ 0评论

第三讲

 

线程的互斥与同步通信

两个线程访问同一对象(取并进行修改)

多线程同时访问一个数据(银行汇款问题)balance余额

线程安全问题,可以用银行转账解释

 

(

1.内部类不能访问局部变量,要想访问就需要加final

2.静态方法不能new内部类的实例对象,内部类可以访问外部类的成员变量

)

public class TraditionalThreadSynchronized{

 

         public static void main(String[] args){

                   new TraditonalThreadSynchronized().init();

}

 

private void init(){

                   Outputer outputer = new OutPuter();

                   new Thread(new Runnable(){

                            @Override

                            public void run() {

                                     try{

                                               Thread.sleep(10);

}

catch(InterruptedException e){

         e.printStackTrace();

}

outputer.output(“lihuoming”);

                           

}

}).start();

 

new Thread(new Runnable(){

                            @Override

                            public void run() {

                                     try{

                                               Thread.sleep(10);

}

catch(InterruptedException e){

         e.printStackTrace();

}

outputer.output(“zhangxiaoxiang”);

                           

}

}).start();

 

}

class Outputer{

         String xxx = “”;

         public void output(String name){

                   int len = name.length();

                   synchronized(xxx){

                            for (int i = 0; i < len; i++){

                                     System.out.println(name.charAt(i));

}

System.out.println();

}

}

}

}

会出现线程问题,解决问题要实现原子行。(比如茅坑问题,只能一个人进去)

把你要保护的代码,用关键词synchronized扩起来,有一把门闩,任何对象都可以当作门闩。

每个线程进来执行的时候需要获取门闩,互斥要用一个对象.

xxx有点多此一举,可以用synchronized(this),实现互斥

 

保护方法内的所用代码,直接在代码前面加上synchronized

public void output(String name)–à public synchronized void output(String name)

静态方法的同步synchronized(Output.class)

public synchronized void output2(String name)

 

以上是线程互斥。

 

第四讲

下面讲线程同步

 

看一道面试题:

子线程循环10次,接着主线程循环100次,接着又回到子线程循环10次,接着再回到主线程又循环100次,如此循环50次。写出程序

public class TraditionalThreadCommunication{

         public static void main(String[] args){

                   new Thread(

new Runnable(){

         @Override

         public void run(){

                   for (int i = 1; i <=50; i++){

                            synchronized(TraditionalThreadCommunication.class){

                                     for (int j = 1; j < = 10; j++){

System.out.println(“sub thread sequence of ” + j + “ look of ” + i);

}

 

}

}

}

}).start();

for (int i = 1; i <=50; i++){

         synchronized(TraditionalThreadCommunication.class){

         for (int j = 1; j < = 100; j++){

                            System.out.println(“main thread sequence of ” + j + “ look of ” + i);

}

}

}                 

}

//第二种方式

final Business  business  =  new Business ();

public static void main2(String[] args){

         new Thread(

new Runnable(){

         @Override

         public void run(){

                   for (int i = 1; i <=50; i++){

business.sub(i);

}

}

}).start();

for (int i = 1; i <=50; i++){

         business.main(i);

}

}

}

第一种基本实现,实现方式不好,不是你执行一下我执行一下。

把相关联的方法放到一个类里面,好维护好更改(高内聚)

内部类

class Business{

         private Boolean bShouldSub = true;

         public synchronized void sub(int i){

                   if (!bShouldSub) {

                            this.wait();

}

for (int j = 1; j < = 10; j++){

System.out.println(“sub thread sequence of ” + j + “ look of ” + i);

                   }

                   bShouldSub = false;

this.notify();

}

 

public synchronized void main(int i){

         if (!bShouldSub){

                            this.wait();

}

for (int j = 1; j < = 100; j++){

System.out.println(“main thread sequence of ” + j + “ look of ” + i);

}

bShouldSub = true;

this.notify();

}

}

 

经验:要用到共同数据(包括同步锁)或共同算法的若干个方法应该归在同一个类身上,这种设计正好体现了高内聚和程序的健壮性

锁是上在代表要操作的资源的类的内部方法中(如Business),而不是线程代码中

if(bShouldSub)可以改成while(bShould), 可以解决伪唤醒

 

5

线程范围内共享数据(底层框架经常用到)

public class ThreadScopeShareData{

         private static int data = 0;

         public static void main(String[] args){

                   for (int i = 0; i < 2; i++){

                            new Thread(new Runnable(){

                                     @Override

                                     public void run(){

                   data = new Random().nexeInt();

System.out.println(Thread.currentThread().getName() + “has put data : ” + data);

 

threadData.put(thread.currentThread(), data);

new A().get();

new B().get();

}

}).start();

}

}

static class A{

         public void get(){

System.out.println(“A from ” + Thread.currentThread().getName() + “get data : ” + data);

}

}

static class B{

public void get(){

System.out.println(“A from ” + Thread.currentThread().getName() + “get data : ” + data);

}

}

}

//两个线程现在拿到的都是一样的,同一份

public class ThreadScopeShareData{

         private static int data = 0;

         private static map<Thread, Integer> threadData = new HashMap<Thread, Interger>();

         public static void main(String[] args){

                   for (int i = 0; i < 2; i++){

                            new Thread(new Runnable(){

                                     @Override

                                     public void run(){

                   data = new Random().nexeInt();

System.out.println(Thread.currentThread().getName() + “has put data : ” + data);

 

threadData.put(thread.currentThread(), data);

new A().get();

new B().get();

}

}).start();

}

}

static class A{

         public void get(){

                   int data = threadData.get(Thread.currentThread());

System.out.println(“A from ” + Thread.currentThread().getName() + “get data : ” + data);

}

}

static class B{

public void get(){

int data = threadData.get(Thread.currentThread());

System.out.println(“A from ” + Thread.currentThread().getName() + “get data : ” + data);

}

}

}

//这时候运行两个线程获取的还是同一份

//data = new Random().nextInt(); 改写为 int data = new Random().nextInt();就可以每个线程单独的数据

 

数据库连接,每个线程都是单独的,事务提交不影响其他的线程

在线程内共享,在线程外部独立

转载请注明:学时网 » 张孝祥老师-java并发编程听课笔记(二)

喜欢 (0)or分享 (0)

您必须 登录 才能发表评论!