⑴ java多线程并发去调用一个类的静态方法,有什么问题
总的结论:java是线程安全的,即对任何方法(包括静态方法)都可以不考虑线程冲突,但有一个前提,就是不能存在全局变量。如果存在全局变量,则需要使用同步机制。x0dx0ax0dx0a如下通过一组对比例子从头讲解:x0dx0a 在多线程中使用静态方法会发生什么事?也就是说多线程访问同一个类的static静态方法会发生什么事?是否会发生线程安全问题?x0dx0apublic class Test {x0dx0a public static void operation(){x0dx0a // ... do somethingx0dx0a }x0dx0a}x0dx0a 事实证明只要在静态函数中没有处理多线程共享数据,就不存在着多线程访问同一个静态方法会出现资源冲突的问题。下面看一个例子:x0dx0apublic class StaticThread implements Runnable {x0dx0a @Overridex0dx0a public void run() {x0dx0a // TODO Auto-generated method stubx0dx0a StaticAction.print();x0dx0a }x0dx0a public static void main(String[] args) {x0dx0a for (int i = 0; i < 100; i++) {x0dx0a new Thread(new StaticThread()).start();x0dx0a }x0dx0a }x0dx0a}x0dx0apublic class StaticAction {x0dx0a public static int i = 0;x0dx0a public static void print() {x0dx0a int sum = 0;x0dx0a for (int i = 0; i < 10; i++) {x0dx0a System.out.print("step " + i + " is running.");x0dx0a sum += i;x0dx0a }x0dx0a if (sum != 45) {x0dx0a System.out.println("Thread error!");x0dx0a System.exit(0);x0dx0a }x0dx0a System.out.println("sum is " + sum);x0dx0a }x0dx0a}x0dx0a 实际执行的结果显示各个线程对静态方法的访问是交叉执行的,但是这并不影响各个线程静态方法print()中sum值的计算。也就是说,在此过程中没有使用全局变量的静态方法在多线程中是安全的,静态方法是否引起线程安全问题主要看该静态方法是否对全局变量(静态变量static member)进行修改操作。x0dx0a 在多线程中使用同一个静态方法时,每个线程使用各自的实例字段(instance field)的副本,而共享一个静态字段(static field)。所以说,如果该静态方法不去操作一个静态成员,只在方法内部使用实例字段(instance field),不会引起安全性问题。x0dx0a 但是,如果该静态方法操作了一个静态变量,则需要静态方法中采用互斥访问的方式进行安全处理。我们来看一下没有使用互斥访问的话会产生怎样的问题:public class StaticAction {x0dx0a public static int i = 0;x0dx0a public static void incValue() {x0dx0a int temp = StaticAction.i;x0dx0a try {x0dx0a Thread.sleep(1);x0dx0a } catch (Exception e) {x0dx0a e.printStackTrace();x0dx0a }x0dx0a temp++;x0dx0a StaticAction.i = temp;x0dx0a }x0dx0a}x0dx0apublic class StaticThread implements Runnable {x0dx0a @Overridex0dx0a public void run() {x0dx0a // TODO Auto-generated method stubx0dx0a StaticAction.incValue();x0dx0a }x0dx0a public static void main(String[] args) {x0dx0a for (int i = 0; i < 100; i++) {x0dx0a new Thread(new StaticThread()).start();x0dx0a }x0dx0a try {x0dx0a Thread.sleep(1000); //预留足够的时间让上面的线程跑完x0dx0a } catch (Exception e) {x0dx0a e.printStackTrace();x0dx0a }x0dx0a System.out.println(StaticAction.i);x0dx0a }x0dx0a}x0dx0a 实际运行结果显示i值为随机的数字。为了实现互斥访问,这时我们需要加入一个synchronized关键字。代码修改如下:x0dx0apublic class StaticAction {x0dx0a public static int i = 0;x0dx0a public synchronized static void incValue() {x0dx0a int temp = StaticAction.i;x0dx0a try {x0dx0a Thread.sleep(1);x0dx0a } catch (Exception e) {x0dx0a e.printStackTrace();x0dx0a }x0dx0a temp++;x0dx0a StaticAction.i = temp;x0dx0a }x0dx0a}x0dx0apublic class StaticThread implements Runnable {x0dx0a @Overridex0dx0a public void run() {x0dx0a // TODO Auto-generated method stubx0dx0a StaticAction.incValue();x0dx0a }x0dx0a public static void main(String[] args) {x0dx0a for (int i = 0; i < 100; i++) {x0dx0a new Thread(new StaticThread()).start();x0dx0a }x0dx0a try {x0dx0a Thread.sleep(1000);x0dx0a } catch (Exception e) {x0dx0a e.printStackTrace();x0dx0a }x0dx0a System.out.println(StaticAction.i);x0dx0a }x0dx0a}x0dx0a 运行结果则必然是100。x0dx0a 加入synchronized关键字的静态方法称为同步静态方法。x0dx0a 在访问同步静态方法时,会获取该类的“Class”对象,所以当一个线程进入同步的静态方法中时,线程监视器获取类本身的对象锁,其它线程不能进入这个类的任何静态同步方法。它不像实例方法,因为多个线程可以同时访问不同实例同步实例方法。这个其实就是操作系统中的用信号量实现进程的互斥与同步问题,如果涉及在同一个类中有多个静态方法中处理多线程共享数据的话,那就变成用信号量解决生产者-消费者问题。也就是说,静态方法是一份临界资源,对静态方法的访问属于进入临界区;对静态变量的修改是一份临界资源,对静态变量的修改属于进入临界区。
⑵ java中多线程地并发运行是什么意思有什么作用.好处
如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。因此我们可以用多线程处理并发运行,提高资源利用率;
举例
假如有一个工厂,工厂里面有10个工人,每个工人同时只能做一件任务。
因此只要当10个工人中有工人是空闲的,来了任务就分配给空闲的工人做;
当10个工人都有任务在做时,如果还来了任务,就把任务进行排队等待;
如果说新任务数目增长的速度远远大于工人做任务的速度,那么此时工厂主管可能会想补救措施,比如重新招4个临时工人进来;
然后就将任务也分配给这4个临时工人做;
如果说着14个工人做任务的速度还是不够,此时工厂主管可能就要考虑不再接收新的任务或者抛弃前面的一些任务了。
当这14个工人当中有人空闲时,而新任务增长的速度又比较缓慢,工厂主管可能就考虑辞掉4个临时工了,只保持原来的10个工人,毕竟请额外的工人是要花钱的。
⑶ java多线程并发的问题
回答这个问题需要先弄清楚线程的概念和线程的生命周期。
线程:是指程序代码的一次执行,是动态的过程。楼主在定义OneTh这个实现Runnable接口类的时候肯定复写了他的run()方法。onet1和onet2是两个线程,也就是说虽然他们的run()方法相同,但是是执行了两次的。
计算机中CPU的调度过程:现在的电脑看上去能同时实现多任务,像是一边上QQ,一边听音乐,还可以一边上网。但计算机中的CPU只有一个,它没有分身术,不可能真正意义上实现同时运行这么多程序。而是采用了一种时间片轮转的方式,为每个应用程序赋予极短的时间,然后高速的在不同的程序间切换,至于每次切换到那个程序,这个要由CPU和线程的优先级来决定。
线程的生命周期:创建时是初始化了这个线程,调用start方法时,是让这个线程进入了可运行状态,注意是可运行,不是正在运行。就像上面说的,在某一时刻CPU具体要运行谁是由CPU和线程的优先级决定的。当线程被CPU运行时,就会开始执行run方法,但可能执行到一半时,CPU又被其他可运行线程抢走,而只能暂停执行。
JAVA程序线程的运行:在我们使用java命令来运行程序时,这时候已经开始了两个线程,一个是main()方法的线程,一个是垃圾回收的线程。当楼主调用start方法开启另外两个线程时。这时候由于CPU来决定运行哪个线程。所以虽然noet1是先开启的,但在执行noet1时,CPU可能又去跑去执行main线程了,然后就会开启onet2.
还有我觉得主线程结束了,只不过其他两个线程仍在继续运行。所以会打印出结果。
楼主如果还有什么不明白的话可以继续问或者相互讨论。
⑷ java 怎样处理高并发
一、背景综述
并发就是可以使用多个线程或进程,同时处理(就是并发)不同的操作。
高并发的时候就是有很多用户在访问,导致系统数据不正确、糗事数据的现象。对于一些大型网站,比如门户网站,在面对大量用户访问、高并发请求方面,基本的解决方案集中在这样几个环节:使用高性能的服务器、高性能的数据库、高效率的编程语言、还有高性能的Web容器。这几个解决思路在一定程度上意味着更大的投入。
使用一般的synchronized或者是lock或者是队列都是无法满足高并发的问题。
二、解决方法有三:
1.使用缓存
2.使用生成静态页面
html纯静态页面是效率最高、消耗最小的页面。我们可以使用信息发布系统来实现简单的信息录入自动生成静态页面,频道管理、权限管理和自动抓取等功能,对于一个大型网站来说,拥有一套高效、可管理的信息发布系统CMS是必不可少的。
3.图片服务器分离
图片是最消耗资源的,僵图片和页面分离可以降低提供页面访问请求的服务器系统压力,并且可以保证系统不会因为图片问题而崩溃。
3.写代码的时候减少不必要的资源浪费:
不要频繁得使用new对象,对于在整个应用中只需要存在一个实例的类使用单例模式.对于String的连接操作,使用StringBuffer或者StringBuilder.对于utility类型的类通过静态方法来访问。
避免使用错误的方式,如Exception可以控制方法推出,但是Exception要保留stacktrace消耗性能,除非必要不要使用 instanceof做条件判断,尽量使用比的条件判断方式.使用JAVA中效率高的类,比如ArrayList比Vector性能好。)
使用线程安全的集合对象vector hashtable
使用线程池
⑸ java中如何实现多进程并发
创建多个线程就可以了,最长用的方法有:
创建类,实现Runnable 接口,重写run方法;
继承Thread 类,重写run方法。
使用线程池。
具体比较麻烦,你查api
给你一个简单的例子看看。
package DuoXianCheng;
public class ThreadText {
public static void main(String[] args) throws Exception {
Runnable rb=new ThreadText().new Thread2();
Thread t3=new Thread(rb,"旺财");
Thread t1=new Thread(rb,"小强");
t1.start();
t3.start();
}
public class Thread2 implements Runnable{
public void run(){
while(true){
try {
Thread.sleep(2000);
System.out.println("当前线程名称:"+Thread.currentThread().getName()+"*****");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
}
⑹ java高并发,如何解决,什么方式解决,高并发
首先,为防止高并发带来的系统压力,或者高并发带来的系统处理异常,数据紊乱,可以以下几方面考虑:1、加锁,这里的加锁不是指加java的多线程的锁,是指加应用所和数据库锁,应用锁这边通常是使用redis的setnx来做,其次加数据库锁,因为代码中加了应用所,所以数据库不建议加悲观锁(排他锁),一般加乐观锁(通过设置一个seq_no来解决),这两个锁一般能解决了,最后做合理的流控,丢弃一部分请求也是必不可少的
⑺ java如何处理高并发
你指的高并发量大概有多少?x0dx0a几点需要注意:x0dx0a尽量使用缓存,包括用户缓存,信息缓存等,多花点内存来做缓存,可以大量减少与数据库的交互,提高性能。x0dx0a用jprofiler等工具找出性能瓶颈,减少额外的开销。x0dx0a优化数据库查询语句,减少直接使用hibernate等工具的直接生成语句(仅耗时较长的查询做优化)。x0dx0a优化数据库结构,多做索引,提高查询效率。x0dx0a统计的功能尽量做缓存,或按每天一统计或定时统计相关报表,避免需要时进行统计的功能。x0dx0ax0dx0a能使用静态页面的地方尽量使用,减少容器的解析(尽量将动态内容生成静态html来显示)。x0dx0a解决以上问题后,使用服务器集群来解决单台的瓶颈问题。x0dx0a基本上以上述问题解决后,达到系统最优。x0dx0ax0dx0a至于楼上有人提到别用JAVA来做,除非是低层的连接数过大(如大量的端口占用需求),这种情况下考虑直接C来写,其他的可以用JAVA来做。x0dx0ax0dx0a可以网上购买视频做教育学习。
⑻ 什么被称为Java的并发
java什么是并发?一起来来了解一下吧。
在Java中,同时执行多个操作的“思想”称为并发,并发完成的每一件事称为线程,java是一种多线程编程语言,一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
拓展:Java需要学习什么?
1、对Java有基本认知。
2、学习Java基础:包括Java语言、Java语法和各种基本算法,了解代码从写好到实现之间的流程。
2、数据库开发:主要包括SQL基础、JDBC编程和JDBC高级应用。
3、DHTML编程:主要包括HTML语言、JS语法、JS对象和DOM编程。
4、Javaweb编程:主要包括servlet开发、JSP开发和AJAX开发。
5、学习真实实训项目,培养实操能力。
今天的分享就是这些了,希望大家喜欢。
⑼ java多线程并发问题怎么解决
java多线程并发问题产生的主要原因是多个线程访问一个实例,导致其中一个线程修改或删除这个实例时,其他线程产生并发问题。
要解决这种并发问题有两种方法:
(1)加上线程锁synchronization
(2)还有个不是办法的办法:不用成员变量,用局部变量