黑马程序员技术交流社区
标题:
java中线程问题
[打印本页]
作者:
陈欢
时间:
2012-7-28 02:43
标题:
java中线程问题
在下面的代码中定义了一个静态方法,方法内部不涉及调用外部变量,比如说实现某种功能,那么这个静态
方法在遇到多线程问题的时候是否会存在安全隐患呢? 是否属于线程安全呢,对这个理解比较模糊。
public class Test implements Runnable {
public static void main(String[] args) {
new Thread(new Test(), "Thread 1").start();
new Thread(new Test(), "Thread 2").start();
}
public static void show() {
int x = 1;
if (x != 0)
System.out.println("输出:" + x);
a++;
}
@Override
public void run() {
while (true) {
show();
}
}
}
作者:
刘同超
时间:
2012-7-28 03:20
安全隐患必须存在,线程所运行的方法没有进行保护。所以当多个线程同时调用一个方法时。就可能出现你在使用方法的时候,我半路杀进来也在使用。
具体保护方式参看这段代码。
public static void main(String[] args) {
new Thread(new Runnable() {
public void run() {
show();
}
}, "Thread 1").start();
new Thread(new Runnable() {
public void run() {
show();
}
}, "Thread 2").start();
}
public static void show() {
int x = 1;
synchronized (Main.class) { // 进行线程保护。加锁是当前类的字节码
if (x != 0) {
System.out.println("输出:" + x);
}
x++; // 楼主,这里是 x 吧。你写的是 a
}
}
复制代码
作者:
刘同超
时间:
2012-7-28 03:33
便于楼主理解,写了一个代码给楼主看。
public static void main(String[] args) {
/*
* 为了方便楼主理解代码大部分都加有注释。
* 楼主第一次运行程序数秒之后,观察控制台是否有错误输出。 肯定有。仔细找。
*
*
* 之后把我打有★★★★★的这两行注释取消掉。
* 楼主第二次运行程序数秒之后,观察控制台是否没有错误输出。肯定没有。随便找。
* 当然,用铁道部xxx的话,就是:不保证奇迹的发生。
*
*
* 最后。创建 init。 注意这的Xianchenganquan换成你的类名。
* 也就是第一行代码。
* */
new Xianchenganquan().init();
}
private void init() {
// 创建Ouppter类
final Ouppter outputer = new Ouppter();
// 创建线程。并启动
new Thread(new Runnable() {
public void run() {
while (true) {
try {
// 等待10毫秒
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 线程调用同一个方法,传入内容
outputer.outoup("12345678901234567890123456789");
}
}
}).start();
// 创建线程。并启动
new Thread(new Runnable() {
public void run() {
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 线程调用同一个方法,传入内容
outputer.outoup("ABCDEFGHIGKLMNOPQRSTUVWXYZ");
}
}
}).start();
}
// 定义一个类。Ouppter
static class Ouppter {
// 类方法。outoup
public void outoup(String name) {
int len = name.length();
// synchronized (Ouppter.class) { // ★★★★★★ 楼主把这句话取消注释了
for (int i = 0; i < len; i++) {
System.out.print(name.charAt(i));
}
System.out.println();
// }
} // ★★★★★★ 还有这个大括号
}
复制代码
作者:
侯宪博
时间:
2012-7-28 06:56
楼主突出static方法和多线程
是不是想问当静态方法结合多线程使用时是否会产生新的隐患
不会的,因为只要不在静态方法中访问外部的非静态成员
而多线程操作中对于共享资源操作做好了同步,不会产生新的问题
也就是说静态结合多线程,需要处理的都是各自的安全问题
不会因为他们的结合而产生新的安全隐患
作者:
刘海源
时间:
2012-7-28 07:18
public class Thread1 implements Runnable {
public static void main(String[] args) {
new Thread(new Thread1(), "Thread 1").start();
new Thread(new Thread1(), "Thread 2").start();
}
public static void show() {
int x = 1; //这里定义的局部变量在show()方法里边所以声生命周期很短
//随着该函数的消失而消失,所以每次执行的时候x都是1自然当在理想的情况下输出的也都是1
if (x != 0) //所以建议别设定成局部变量
System.out.println(Thread.currentThread().getName()+"输出:" + x);
x++;
}
// synchronized(Thread1.class){
//if (x != 0) //所以建议在这串代码的外部加上同步锁因为是static所以用的锁是类对象
//
// System.out.println(Thread.currentThread().getName()+"输出:" + x);
// x++; }
//Thread 2输出:1
//Thread 2输出:1
//Thread 2输出:1
//Thread 2输出:1
//Thread 2输出:1
//Thread 2输出:1
//Thread 2输出:1
//Thread 2输出:1
//Thread 2输出:1
//Thread 2输出:1
//Thread 2输出:1
//Thread 2? 这里就发生了问题,没有输出,我给你解释一下吧,你不是创建了两个线程
//对象么,所以这两个线程对象在抢夺CPU资源,而CPU将最终的执行权给谁
// 都是随机的,如果你没有采取安全措施的话,那么当线程t1执行时进如show()方法后,有肯能
// 当在判断完if语句后,只打印出了线程的名字后他的执行权就被t2给抢夺走了,于是t2就开始
// 执行run()方法,这样还没等X输出出来呢就被切换到了另一个线程了,发生了安全问题
@Override
public void run() {
while (true) {
show();
}
}
}
无标题.png
(23.94 KB, 下载次数: 59)
下载附件
2012-7-28 07:18 上传
作者:
吴立杰
时间:
2012-7-28 08:15
会有安全隐患的,你要同步就没事了。这个跟静态没有关系。如果是操作静态的数据,静态的数据时共享的数据,也扯不上安全问题。所以感觉你弄乱了
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2